复制构造函数混淆

Copy constructor confusion

任何人都可以向我解释为什么在此代码中定义 MyClass ( const MyClass & src ) { m_X = src . m_X; } 的原因吗?如果没有这行代码,它也能正常工作,并给出相同的输出,在本例中为 32。有和没有有什么区别?我读到复制构造函数是自动生成的,但是当您在 class 中定义了指针时,您应该定义它,但在这种情况下我不明白为什么。

代码如下:

#include <iostream>
using namespace std;

class MyClass
{
public:
    MyClass ( int x ) : m_X ( new int ( x ) ) {}
    MyClass ( const MyClass &src ) 
    {
        m_X = src.m_X; 
    }

    void  print ( void ) const 
    { 
        cout << *m_X; 
    }

private:
    int * m_X;
};


int main ( void )
{
    MyClass a ( 32 ), c = a;
    c.print ();

    return 0;
}

你得到相同输出的原因是你正在做一个浅拷贝,就像编译器会做的那样。仅仅复制一个指针是不够的。您需要创建一个新指针,然后将其值设置为您要复制的内容的副本。一个合适的构造函数看起来像

MyClass ( const MyClass & src ) : m_X(new int(*src.m_X) {}

现在副本有自己的独立指针,具有相同的值。

另请注意,您需要一个析构函数来删除内存和一个适当的复制赋值运算符,因为默认复制赋值运算符将执行与默认复制构造函数相同的操作。

默认复制构造函数以及您的复制构造函数执行成员智能复制(或浅复制)。在这种情况下,您有一个指针,其值是数据所在位置的地址。此地址复制的内容。

如其他帖子所述,您需要更好地管理指针。

编译器生成的一个(和你的)的问题是它复制了指针。您现在有两个指针 c.m_xa.m_x 都指向同一个堆分配对象。谁拥有它?如果你删除 a 会发生什么,它应该删除它分配的内存(你不正确地这样做),但 c 仍然指向它。

因此有 std::shared_ptr。它是为这种情况设计的,它执行 Right Thing By Magic

int * m_X替换为std::shared_ptr<int> m_X