首页 > 代码库 > 深拷贝与浅拷贝

深拷贝与浅拷贝

在 C++ 中,赋值和拷贝是不同的,

    1)拷贝构造函数是对未初始化的内存进行初始化操作

    2)而赋值是对现有的已经初始化的对象进行操作。(这里我对“已经初始化”的理解是已经调用了构造函数,并且构造函数体可以未执行,只要调用到即可),赋值函数应该给所有数据成员都初始化。

       3)重点:包含动态分配成员的类 应提供拷贝构造函数,并重载"="赋值操作符。

4)可以说,C++中什么时候有临时对象产生,此时刻c++一定要调用拷贝构造函数

 

当用一个已初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用。也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数:一个对象以值传递的方式传入函数体 一个对象以值传递的方式从函数返回 一个对象需要通过另外一个对象进行初始化。

 

如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝。位拷贝又称浅拷贝

 

首先定义String类,而并不实现其成员函数。

1.    Class String{

2.    public:

3.        String(const char *ch=NULL);//默认构造函数

4.        String(const String &str);//拷贝构造函数

5.       ~String(void);

6.       String &operator=(const String &str);//赋值函数

7.    private:

8.       char *m_data;

9.    };

    位拷贝拷贝的是地址,而值拷贝则拷贝的是内容。如果定义两个String对象ABA.m_dataB.m_data分别指向一段区域,A.m_data=http://www.mamicode.com/windows,B.m_data=http://www.mamicode.com/linux;

    如果未重写赋值函数,将B赋给A;则编译器会默认进行位拷贝,A.m_data=http://www.mamicode.com/B.m_data

    则A.m_dataB.m_data指向同一块区域,虽然A.m_data指向的内容会改变成”linux,但是这样容易出现这些问题:

     (1):A.m_data原来指向的内存区域未释放,造成内存泄露。

     (2):A.m_dataB.m_data指向同一块区域,任何一方改变都会影响另一方

     (3):当对象被析构时,B.m_data被释放两次。

    对于编译器,如果不主动编写拷贝函数和赋值函数,它会以“位拷贝”的方式自动生成缺省的函数。

深拷贝与浅拷贝