美文网首页
C++ 拷贝构造函数

C++ 拷贝构造函数

作者: 我阿郑 | 来源:发表于2021-12-23 16:23 被阅读0次

    一、拷贝构造函数

    拷贝构造函数是一种特殊的构造函数;
    拷贝构造函数的含义: 以一个对象为蓝本,来构造另一个对象;

    • 它是构造函数,所以函数名是类名、没有返回值
    • 它是特殊的构造函数:参数形式是固定的
    class Object
    {
    public:
        Object( const Object& other );
    };
    

    拷贝构造函数从来不显式调用,而是由编译器隐式地调用
    在以下三种情况:

    (1)定义对象

    Object a;
    Object b(a);  // 或写成 Object b = a;
    

    (2)动态创建对象

    Object a;
    Object* p = new Object(a);
    

    (3)函数的传值调用

    void Test(Object obj);
    

    二、 注意 : 区分“构造”与“赋值”

    构造:

    Object a;
    Object b = a;  // 或写作  Object b(a);
    // 此为“构造”,在创建对象的时候给初值,拷贝构造函数被调用
    

    赋值:

    Object a(1,2);
    Object b; // 调用了构造函数创建了b对象
    b = a;  // 此为“赋值”,不会调用拷贝构造函数
    

    三、注意 : 可以访问同类对象的private成员

    在拷贝构造函数,可以访问参数对象的任意成员,因为它们是同类,所以访问不受限制。

    Object(const Object& other)
    {
        this->a = other.a;
        this->b = other.b;
    }
    

    四、默认的“拷贝构造函数”

    当没有书写拷贝构造函数时,编译器会默认提供一个拷贝构造函数。
    默认的拷贝动作:将每一个成员逐个拷贝。也就是说,在多数情况下,我们无需操心,编译器会帮我们完成成员的拷贝动作。

    ⚠️ 注意:除非必要,不要添加拷贝构造函数。
    一旦你决定了要添加拷贝构造函数,请仔细检查:

    (1)所有的成员变量,要依次拷贝 (所有成员变量,不要遗漏)

    (2)调用父类的拷贝构造函数 (要么不负责,要么负责全部事情)

    问题:拷贝构造函数非常麻烦,容易遗漏,为什么还要自己写一个拷贝构造函数呢?

    当以下情况发生时,需要添加拷贝构造函数

    class Text
    {
    public:
        // 构造函数
        Text(const char* str)
        {
            // 申请一块内存, 保存此字符串
            m_size = strlen(str) + 1;
            m_buf = new char[m_size];
            strcpy(m_buf, str);     
        }
        ~Text()
        {
            // 释放此字符串
            delete [] m_buf;
        }
    private:
        int m_size;
        char* m_buf;
    };
    
    
    int main()
    {
          // 定义第一个对象
        Text t1("helloworld");
    
          // 第二个对象以t1为蓝本进行拷贝
        Text t2(t1);
    
        return 0;
    }
    
    

    对象创建

    对象t1.m_buf,指向一块内存
    对象t2拷贝了t1, t2.m_buf指向了同一块内存

    对象析构

    对象t1析构, delete [] m_buf;
    对象t2析构,delete [] m_buf;出错,此块内存已经被delete

    ⚠️ 错误的根本原因:应该拷贝其数据,而不是拷贝其指针

    解决办法

    (1) 正规解决方法 : 添加拷贝构造函数,拷贝其具体的数据
    Text(const Text& other)
    {
        m_size = other.m_size;
        m_buf = new char[m_size];
        strcpy(m_buf, other.m_buf);
    }
    

    此种情况称为“深度拷贝”

    (2) 省事的办法

    禁止用户进行拷贝构造,将拷贝构造函数设定为private,一般不这么做

    private:
        Text(const Text& other)
        {
        }
    

    相关文章

      网友评论

          本文标题:C++ 拷贝构造函数

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