目录
一. 类的默认成员函数
二.六种默认成员函数
1、构造函数
1.1 构造函数的作用
1.2 特性
1.3 默认构造函数
2、析构函数
2.1 析构函数的作用
2.2 析构函数的用法
3、拷贝构造函数
3.1 拷贝构造函数的作用
3.2 特征
3.3 默认拷贝构造函数
三.总结
类与对象(上):C++初阶学习第三弹——类与对象(上)-CSDN博客
一. 类的默认成员函数
如果一个类中什么成员都没有,简称为空类。而默认成员函数就是不用写,编译器会自动生成的函数。任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。
二.六种默认成员函数
1、构造函数
1.1 构造函数的作用
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date a1;
a1.Init(2023, 7, 26);
Date a2;
a2.Init(2024, 7,29 );
return 0;
}
对于Date类,可以通过 Init 公有方法给对象设置日期,但如果每次创建对象时都调用该方法设置 信息,未免有点麻烦,那能否在对象创建时,就将信息设置进去呢?
构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证 每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。
1.2 特性
1. 函数名与类名相同。
2. 无返回值。
3. 对象实例化时编译器自动调用对应的构造函数。
4. 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。
5.如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,
构造函数的形式如下:
class Date
{
public:
// 1.无参构造函数
Date()
{}
// 2.带参构造函数
Date(int year, int month, int day)
{
_year = year;
比特就业课
5. 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦
用户显式定义编译器将不再生成。
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
void TestDate()
{
Date d1; // 调用无参构造函数
Date d2(2015, 1, 1); // 调用带参的构造函数
// 注意:如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数声明
// 以下代码的函数:声明了d3函数,该函数无参,返回一个日期类型的对象
// warning C4930: “Date d3(void)”: 未调用原型函数(是否是有意用变量定义的?)
Date d3();
}
1.3 默认构造函数
构造函数在类中实际上是可以自动生成的,当我们不去写默认构造函数时,它就会在类中自动生成,但我们需要注意的是,默认生成的构造函数是无参的,且它会初始化一个随机值
class Date
{
public:
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
d1.Print();
return 0;
}
如下图:
2、析构函数
2.1 析构函数的作用
析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由 编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。
2.2 析构函数的用法
1. 析构函数名是在类名前加上字符 ~。:~类名()
2. 无参数无返回值类型。
3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构 函数不能重载
4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。
如下:
class Stack
{
public:
Stack(int capacity=4) //构造函数
{
_capacity = capacity;
_arr = (int*)malloc(sizeof(int) * _capacity);
_size = 0;
}
~Stack() //析构函数
{
free(_arr);
_arr = nullptr;
_capacity = 0;
_size = 0;
}
private:
int* _arr;
int _capacity;
int _size;
};
int main()
{
Stack s();
return 0;
}
对于上面那种需要申请资源的类类型,我们可以把析构函数写出来,对于并没有申请资源的类类型,我们可以不写析构函数,让编译器默认生成
3、拷贝构造函数
3.1 拷贝构造函数的作用
拷贝构造函数的作用就是将一个已经构造好的函数拷贝给另一个函数。
3.2 特征
拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错, 因为会引发无穷递归调用。
拷贝构造函数只有单个形参 ,该形参是对本 类类型对象的引用 ( 一般常用 const 修饰 ) ,在用 已存
在的类类型对象创建新对象时由编译器自动调用 。
class Date
{
public:
Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1(2024, 7, 27);
Date d2(d1);
return 0;
}
3.3 默认拷贝构造函数
若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按 字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。
注意:类中如果没有涉及资源申请时,拷贝构造函数是否写都可以;一旦涉及到资源申请 时,则拷贝构造函数是一定要写的,否则就是浅拷贝。
class Date
{
public:
Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << " " << _month << " " << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1(2024, 7, 27);
Date d2(d1);
d2.Print();
return 0;
}
三.总结
希望给大家带来一定的帮助,下节我会接着讲解关于类和对象—中阶的内容
感谢大佬们的支持