复制构造函数混淆
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_x
和 a.m_x
都指向同一个堆分配对象。谁拥有它?如果你删除 a 会发生什么,它应该删除它分配的内存(你不正确地这样做),但 c 仍然指向它。
因此有 std::shared_ptr
。它是为这种情况设计的,它执行 Right Thing By Magic
将int * m_X
替换为std::shared_ptr<int> m_X
任何人都可以向我解释为什么在此代码中定义 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_x
和 a.m_x
都指向同一个堆分配对象。谁拥有它?如果你删除 a 会发生什么,它应该删除它分配的内存(你不正确地这样做),但 c 仍然指向它。
因此有 std::shared_ptr
。它是为这种情况设计的,它执行 Right Thing By Magic
将int * m_X
替换为std::shared_ptr<int> m_X