- 构造函数和析构函数
- 构造函数:对象创建时调用构造函数,构造函数是初始化对象的属性
- 析构函数:对象在销毁前调用析构函数,析构函数做清理工作
- 构造函数分类:无参构造,有参构造,拷贝构造
- 编译器给类提供了什么函数:默认构造函数(无参),默认拷贝构造,析构函数,默认的赋值函数
- 如果自己提供了构造函数,那么编译器不会提供默认的构造函数,但是会提供默认的拷贝构造函数
- 如果自己提供了拷贝构造函数,那么编译器不会提供任何默认构造函数
- 构造函数,没有返回值,没有void
- 析构函数不能重载,没有参数,没有返回值,没有void
- 匿名对象
- 没有名字的对象,他的生命周期在当前行
- 当前面有Copy copy; 后面不就能这样写Copy(copy)
- 调用拷贝构造函数的时机
- 一个对象去初始化另一个对象时
- 对象做函数参数时
- 看编译器:返回局部对象时,有的调用,有的不调用
- 多个对象的构造函数调用顺序
- 先调用成员对象,成员对象的调用顺序看定义前后,最后调用本身的构造函数
- 析构函数调用的顺序和构造函数相反
- 为什么要写初始化列表:当成员对象没有默认构造时,我们要调用其他构造函数是,需要显示的调用,这时要写初始化列表
- 深浅拷贝
- 如果类内有指针,并且该指针指向申请的堆空间,这时只使用默认的拷贝构造函数,那么会出现浅拷贝问题,(一块空间在析构函数中被释放两次)
- 深拷贝:自己写的拷贝构造函数,申请一块空间,把旧空间的数据拷贝到新空间
拷贝构造调用时机
class Maker
{
public:
Maker()
{
cout << "无参构造函数" << endl;
}
Maker(int a)
{
cout << "有参构造函数" << endl;
}
Maker(const Maker &maker)
{
cout << "拷贝构造函数" << endl;
}
~Maker()
{
cout << "析构函数" << endl;
}
};
// 1.对象以值方式给函数参数
void func(Maker m)//Maker m=m1;
{
}
void test01()
{
Maker m1;
func(m1);
}
//2.用一个已有的对象去初始化另一个对象
void test02()
{
Maker m1;
Maker m2(m1);
}
//3.函数的局部对象以值的方式从函数返回,vs Debug(调试)模式下,会调用拷贝构造,vs Release(发行)模式下不会调用拷贝构造,qt也不调用
Maker func2()
{
//局部对象
Maker m;
cout << "局部对象的地址:" << &m << endl;
return m;
}
void test03()
{
Maker m1 = func2();
cout << "m1对象的地址:" << &m1 << endl;
}
使用指针时的写法:
#include <iostream>
using namespace std;
class Copy {
public:
Copy() {
cout << "no params constructor" << endl;
}
Copy(int a) {
cout << "have params constructor" << endl;
}
Copy(const Copy &co) {
cout << "copy constructor" << endl;
}
Copy(const Copy *co) {
cout << "copy constructor" << endl;
}
~Copy() {
cout << "deconstructor" << endl;
}
};
#include <iostream>
#include "./copy.cpp"
using namespace std;
void test() {
cout << "------------------------------" << endl;
Copy();
Copy(1);
Copy c1;
Copy c2(1);
Copy c3(c1);
Copy c4 = c1;
Copy c5 = 1;
cout << "------------------------------" << endl;
Copy *c6 = new Copy();
Copy *c7=new Copy(1);
Copy *c8 = new Copy(*c7);
Copy *c9 = new Copy(c7);
}
int main() {
test();
system("pause");
return EXIT_SUCCESS;
}