析构与构造函数,拷贝构造函数,赋值构造函数
1 构造函数
当创建对象时,被调用来对类的数据成员进行初始化和分配内存。(构造函数的命名必须和类名完全相同)
编译器会加入的默认成员函数:
- 默认构造函数和拷贝构造函数
- 析构函数
- 赋值函数(赋值运算符)
- 取值函数
注意: 构造函数可以被重载,可以有多个, 析构函数只能有一个,不能被重载,不带参数
构造函数重载实现
class A
{
int m_i;
public:
A() { cout << "无参构造函数" << endl; }
A(int i) : m_i(i) { cout << "带参数 " << i << " 的构造函数" << endl; }
};
2 拷贝构造函数
基于同一类的一个对象构造和初始化另一个对象
拷贝构造函数被调用的场景:
- 一个对象以值传递的方式传入函数体
- 一个对象以值传递的方式从函数返回
- 一个对象需要通过另一个对象进行初始化
如果用户没有自定义拷贝构造函数,但是在代码中使用到了拷贝构造函数,编译器就会生成默认的拷贝构造函数,但如果用户定义了拷贝构造函数,编译器就不会生成。
系统中默认的拷贝构造函数的工作方式是内存拷贝(浅拷贝)
浅拷贝:复制对象时,让新旧两个对象指向内存中的同一块内容,(只复制指针,但指针所指向的空间内容并没有复制,而是让两个对象共用
深拷贝:在复制这个对象的时候为新对象在外部做了对立复制
拷贝构造函数的实现:
A(const A &other) : m_i(other.m_i) { cout << "拷贝构造函数" << endl; }
3 赋值构造函数
当一个类的对象向该类的另一个对象赋值时,就会调用到该类的赋值函数
当没有重载赋值函数(赋值运算符)时,通过默认赋值函数来进行赋值操作
A &operator=(const A &other)
{
this->m_i = other.m_i;
cout << "赋值构造函数" << endl;
}
拷贝构造函数和赋值函数的区别
- 拷贝构造函数是一个对象初始化一个内存区域,这块内存是新对象的内存区,而赋值函数是对一个已经被初始化的对象来进行赋值操作。
class A;
A a;
A b=a; //调用拷贝构造函数(b不存在)
A c(a) ; //调用拷贝构造函数
/****/
class A;
A a;
A b;
b = a ; //调用赋值函数(b存在)</span>
- 拷贝构造函数大多数情况下是复制指针对象,而赋值函数大多数情况是引用指针对象 ???(有点没懂)
- 实现不一样。拷贝构造函数通过参数的对象初始化,产生一个对象。赋值函数则是把一个新的对象赋值给一个原有的对象,如果原来的对象中有内存分配要先把内存释放掉,而且还要检查以下两个对象是不是同一个对象,如果是,不做任何操作,直接返回。
*如何不写拷贝构造,又不用私有构造函数 : 将他们声明为私有函数,函数体为空
class A
{
private:
A(const A& a); //私有拷贝构造函数
A& operate=(const A& a); //私有赋值函数
}
- 对象不存在,且没用别的对象来初始化,就是调用了构造函数;
- 对象不存在,且用别的对象来初始化,就是拷贝构造函数;
- 对象存在,用别的对象来给它赋值,就是赋值函数;
https://blog.csdn.net/zcyzsy/article/details/52132936
https://www.cnblogs.com/liushui-sky/p/7728902.html