美文网首页程序员
c/c++/c++11 浅拷贝和深拷贝

c/c++/c++11 浅拷贝和深拷贝

作者: mfdalf | 来源:发表于2020-09-28 16:14 被阅读0次
    2.jpg

    目录

    1 c++拷贝

    1.1 拷贝构造函数

    1.2 浅拷贝

    1.3 深拷贝

    2 c语言拷贝

    2.1 浅拷贝

    2.2 深拷贝

    3 c++11 深拷贝

    正文

    1 c++拷贝

    1.1 拷贝构造函
    c++通过拷贝构造函数实现对象拷贝.所以先介绍一下拷贝构造函数.
    实例:

    class CA
    {
     public:
      CA(int b,char* cstr)
      {    ...  }
      CA(const CA& C)
      {
       a=C.a;
       str=C.str
      }
     private:
      int a;
      char *str;
    };
    

    CA A(100,"123")//构造函数赋值
    CExample B=A;//拷贝构造函数赋值
    CExample C(A);//拷贝构造函数赋值
    CExample D; D=A;//赋值构造函数赋值
    g_fun(A);//传值拷贝调用对象构造函数

    拷贝构造函数实现分析:
    调用g_Fun()时,会产生以下几个重要步骤:
    (1).函数调用传值拷贝,会先会产生一个临时变量,就叫 C 吧。
    (2).然后调用拷贝构造函数把A的值给C.整个这两个步骤有点像:CA C(A);
    (3).等g_Fun()执行完后, 析构掉 C 对象。C对象完成了在g_Fun()函数内部的工作.
    1.2 浅拷贝
    浅拷贝只拷贝基本数据类型(非指针变量).
    对于指针变量,对象B的指针变量会指向对象A的指针变量内存,不会拷贝.
    类缺省拷贝构造函数是浅拷贝.上例中的拷贝构造函数的实现就是浅拷贝.
    浅拷贝的问题是如果对象中变量带有指针,则会发生错误.因为两个指针指向同一个内存,一个对象修改,另一个对象的值也被更改了.
    当在析构的时候,会发生两次free同一个内存,造成错误.

    下面的link介绍了浅拷贝和c的简单神拷贝.c++深拷贝参见1.3节,c的高级深拷贝参见2.2节。
    参见https://blog.csdn.net/cyy_0802/article/details/80374812
    1.3 c++深拷贝
    在拷贝构造函数中分配内存,将入参对象的指针变量指向的内存,全部拷贝一份就是深拷贝。
    实例分析

    class CA
    {
     public:
      CA(int b,char* cstr)
      {
       a=b;
       str=new char[b];
       strcpy(str,cstr);
      }
      CA(const CA& C)
      {
       a=C.a;
       str=new char[a]; //深拷贝
       if(str!=0)
        strcpy(str,C.str);
      }
     private:
      int a;
      char *str;
    };
    

    CA A(10,"Hello!");//构造函数初始化对象。
    CA B=A; //拷贝构造函数.
    上例将str的内容拷贝一份,实现了深拷贝.
    扩展问题,如果类中变量不是char* str,而是另一个对象的指针会怎么样?

    class CB
    {
     public:
        CB(int b,CA* q)
      {  ...} 
      CB(const CB& C)
      {  
            aa=C.b; 
            p(C.q); //嵌套调用CA的拷贝构造函数做深拷贝.CA的拷贝构造函数见上例
        }
        private:
        int aa;
      CA *p;
    };
    CA A(10,"Hello!");//先要创建出类中组合的对象,然后才能拷贝.
    CB AA(11,A);//初始化AA
    CB BB=AA;//拷贝构造函数
    

    2 c语言拷贝

    2.1 浅拷贝
    和上面的c++浅拷贝一样. 两个指针指向同一个内存.

    char *p,*q="abc";
    p=q;
    

    2.2 深拷贝
    (1) 如果struct中没有指针变量
    直接拷贝内存即可.

    struct CC *p,*q;
    q=(struct CC*)malloc(sizeof(struct CC));
    q->a=100;
    ...//struct 赋值
    memcpy(p,q);
    

    (2) 如果struct中带有指针变量
    需要自己实现拷贝函数,将每个item拷贝一份.(实现类似c++的拷贝构造函数)

    typedef struct Node//结构体
    {
    int size;
    char *data;
    }S_Node;
    void CopyNode(S_Node *node3, S_Node node1)//CopyNode 函数实现结构体变量的深拷贝
    {
    node3->size = node1.size;
    node3->data = (char *)malloc(node3->size + 1);//申请空间
    assert(node3->data != NULL);
    strcpy(node3->data, node1.data);
    }
    S_Node node1;
    node1.data = (char *)malloc(sizeof(char)*100);
    S_Node node3;
    CopyNode(&node3, node1);
    

    扩展情况:如果将char *data换成struct S_NodeA *nodeA会怎么样呢?

    void CopyStruct(S_Node *node3, S_Node node1)//CopyNode 函数实现结构体变量的深拷贝
    {
        node3->size = node1.size;
        node3->data = (char *)malloc(node3->size + 1);//申请空间
        CopyNode(&nodeA,node1);
    }
    

    CopyStruct将非struct的item拷贝一份。nodeA需要嵌套拷贝.调用拷贝S_Node的函数CopyNode完成拷贝.
    总结:浅拷贝就是指针赋值,不分配内存,两个指针指向一个内存. 深拷贝就是拷贝指针指向的内存.如果有嵌套对象的话,嵌套拷贝.

    3 C++11 深拷贝

    c++11 使用移动构造函数实现深拷贝
    移动构造函数的原理是,指针A和B同时指向一块内存,然后将原来的A指针置NULL. 这样避免了两个指针指向同一个内存,也避免了内存拷贝.

    本文如对您有帮助,请随手点个赞,谢谢

    相关文章

      网友评论

        本文标题:c/c++/c++11 浅拷贝和深拷贝

        本文链接:https://www.haomeiwen.com/subject/xugduktx.html