关于深浅拷贝网上到处都是解释,大都解释的不错,这里再次总结,原因有二:

1.温故而知新;2.把所学习到的知识总结归纳。

进入正题,深浅复制都是由于使用复制构造函数来初始化新创建的对象。

先谈谈概念:

浅复制(浅拷贝):被复制对象的所有成员的值都和原来的对象的成员值保持一致。

比如:


class String
{
private:
    char * str;
    int len;
public:
    String()
    {
        len = 4;
        str = new char[4];
        std::strcpy(str, "C++");
    }  
    String(const char * c)
    {
        len = std::strlen(c);
        str = new char[len+1];
        std::strcpy(str, c);
    }
};
//创建String的对象
String str1;
//下面将造成浅复制
String str2 = str1;//使用默认的复制构造函数

上面的代码无疑会造成浅复制,因为默认的复制构造函数逐个复制非静态成员,复制的是成员的值。在程序清单中:

   String str2 = str1;

与下面的代码等效:

   String str2;

   str2.len = str1.len;

   str2.str = str1.str;

这样导致的问题显而易见,那就是str1和str2的成员变量str的内容相同,即他们指向同一块内存,这是一个很严重的问题,当其中任意的一个销毁,也就是意味着str指向的内存释放,而str1和str2终将会走向生命的尽头,也就意味着同一块内存被销毁两次,这就会带来意想不到的后果。这通常是内存管理不善的表现。

   那如何可以解决上述浅复制的问题呢?这里我们就得谈谈深复制了。

深复制(深拷贝):被复制对象会把自己所有的非引用字段复制给新的对象相印的字段,同时也将在新的对象中开辟新的空间来存放被复制对象的引用字段指向的内容。

这样就得在类中显示的定义复制构造函数,如下:


String::String(const String & s)
{
    len = s.len;
    str = new char[len]+1];//alloc place
    str::strcpy(str,s.str);
    //.......
}

   总而言之,深拷贝就是在拷贝的同时自己开辟了空间来存储被复制对象中指针所指向的内容。这样也就解决了浅拷贝考虑不周全带来的问题。