简述拷贝构造函数和赋值运算符

拷贝构造函数和赋值运算符都是进行值传递,将一个对象的值传递给另一个对象。从表面上看,实现的结果是相同的,但是在内部来看,而二者是有很大差别的。

拷贝构造函数

拷贝构造函数就是在类的内部通过创建一个新的实例对象,来实现拷贝构造,用已有的实例化对象来初始化新创建的对象。拷贝构造函数一般有在以下几种情况时会调用。

  1. 在函数中,复制对象,作为参数传给函数。
  2. 复制对象,作为函数的返回值。
  3. 通过另一个同类化的对象来初始化一个新的对象。

一般情况下,如果没有显式的声明一个拷贝构造函数,那么编译器就会自动生成一个默认的拷贝构造函数。这个默认的拷贝构造函数会自动完成对象之间的浅拷贝。如果想要禁用这个构造函数,使用关键字delete

赋值运算符

赋值运算符从结果上来看,其效果和拷贝构造的结果是一样的,但是赋值运算符实际上并不创建新的对象,而是将一个值赋值给一个已有的对象,进行值传递。

关于深拷贝和浅拷贝

关于浅拷贝和深拷贝的区别主要是在类占用的系统资源在对象进行拷贝的时候是否会同步复制。如果资源进行了复制,说明是深拷贝,如果资源没有被复制 ,说明是浅拷贝。浅拷贝容易发生内存泄露以及出现野指针的现象。例如:对象A的指针指向一块内存区域,而对象B的指针也指向同一块内存区域,表面上来看,对象A初始化对象B,没有问题。但是,当对象通过指针A释放了它所占用的内存空间时,对象B的指针就就变成了野指针,发生内存泄露。对于这种情况,一般发生于类内有成员通过动态来申请空间的情况下。

实例

class Person
{
private:
int a;
public:
Person();
Person(const Person& A)
{
a = A.a;
}
};