zoukankan      html  css  js  c++  java
  • C++有关拷贝构造函数(默认/浅/深拷贝构造函数)

    拷贝结构函数顾名思义就是复制对象。

    先讲一下默认拷贝函数:

    默认拷贝就是直接赋值,让程序调用默认拷贝结构函数。

    Student p1;
    
    Student p2 = p1//或者Student p2(p1);
    程序开始运行时,创建p1对象,p1对象的构造函数从堆中分配空间并赋给数据成员pName,执行,p2=p1时,因为没有定义拷贝构造函数,于是就调用默认拷贝构造函数,
     
    使得p2与p1完全一样,并没有新分配堆空间给p2,  p1与p2的pName都是同一个值。析构p2时,将堆中字符串清成空串,然后将堆空间返还给系统;
     
    析构p1时,因为这是pName指向的是空串,所以第三行输出中显示的只是Destructing,当执行 delete pName ; 按道理系统应该报错,但在gcc中没有。

    重点讲一下,深拷贝和浅拷贝。

    这里借鉴一个前辈的例子:(前辈写的很好,大家可以看下)

    https://www.cnblogs.com/raichen/p/4752025.html

    #include <iostream>
    #include <cstring>
    class Person 
    {
    public :
             
        // 构造函数
        Person(char * pN)
        {
            cout << "一般构造函数被调用 !
    ";
            m_pName = new char[strlen(pN) + 1];
            //在堆中开辟一个内存块存放pN所指的字符串
            if(m_pName != NULL) 
            {
               //如果m_pName不是空指针,则把形参指针pN所指的字符串复制给它
                 strcpy(m_pName ,pN);
            }
        }        
           
        // 系统创建的默认复制构造函数,只做位模式拷贝
        Person(Person & p)    
        { 
            //使两个字符串指针指向同一地址位置         
            m_pName = p.m_pName;         
        }
     
        ~Person( )
        {
            delete m_pName;
        }
             
    private :
        char * m_pName;
    };
     
    void main( )
    { 
        Person man("lujun");
        Person woman(man); 
         
        // 结果导致   man 和    woman 的指针都指向了同一个地址
         
        // 函数结束析构时
        // 同一个地址被delete两次
    }
     
     
    // 下面自己设计复制构造函数,实现“深拷贝”,即不让指针指向同一地址,而是重新申请一块内存给新的对象的指针数据成员
    Person(Person & chs);
    {
         // 用运算符new为新对象的指针数据成员分配空间
         m_pName=new char[strlen(p.m_pName)+ 1];
     
         if(m_pName)         
         {
                 // 复制内容
                strcpy(m_pName ,chs.m_pName);
         }
       
        // 则新创建的对象的m_pName与原对象chs的m_pName不再指向同一地址了
    }

    因为编译不同,可能不能通过编译,但这不是重点。

    直接利用浅拷贝,m_pName = p.m_pName,后者复制给前者,但资源(堆空间)并未复制给前者,相当于这两个都同时指向同一地址,造成或释放两次内存。

    深拷贝上面例子可以看到,会给它新申请一个空间。

    注意:(引用)“如果需要析构函数,则一定需要拷贝构造函数和赋值操作符。

    什么情况使用复制构造函数:

    类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数:


    (1)一个对象以值传递的方式传入函数体 


    (2)一个对象以值传递的方式从函数返回 


    (3)一个对象需要通过另外一个对象进行初始化。

    同时别人推荐的读的文章:https://blog.csdn.net/fdsafwagdagadg6576/article/details/51723823

    想要了解跟多可以了解一下这篇文章:《面向对象进价--拷贝构造函数》

    然后可以看下例子:多继承的例子(附详解)

  • 相关阅读:
    条件概率和链式法则 conditional probability & chain rule
    如何训练一个神经网络?
    高斯贝叶斯分类器
    LDA
    机器学习中的数学-线性判别分析(LDA)
    理解矩阵
    pca数学原理(转)
    SVM入门
    Top 10 Machine Learning Algorithms For Beginners
    vfp
  • 原文地址:https://www.cnblogs.com/Mayfly-nymph/p/8853006.html
Copyright © 2011-2022 走看看