https://stackoverflow.com/a/3278636/462608
Class::Class( const char* str )
{
stored = new char[srtlen( str ) + 1 ];
strcpy( stored, str );
}
在这种情况下,存储成员的成员方式复制不会复制缓冲区(只会复制指针)
但是这里的内存是由new
. 那为什么仍然说只有指针会被复制而不是整个缓冲区呢?
https://stackoverflow.com/a/3278636/462608
Class::Class( const char* str )
{
stored = new char[srtlen( str ) + 1 ];
strcpy( stored, str );
}
在这种情况下,存储成员的成员方式复制不会复制缓冲区(只会复制指针)
但是这里的内存是由new
. 那为什么仍然说只有指针会被复制而不是整个缓冲区呢?
在您的班级Class
中,您有一个名为stored
. 当一个实例Class
被复制时,例如
Class a("hello");
Class b = a; // Copying a
然后指针stored
将被复制,所以你有两个具有相同指针的对象。然后,如果您delete
将指针放在一个对象中,那么另一个对象仍然具有其指针,该指针现在将指向未分配的内存。
这就是为什么您需要创建一个复制构造函数:
Class(const Class& other)
{
stored = new char[strlen(other.stored) + 1];
strcpy(stored, other.stored);
}
现在,如果您有上面的复制构造函数,当像我的第一个代码片段那样发生复制时,将分配一个新字符串,并复制来自另一个实例的内容。当然,在两个对象实例之间进行赋值时,您还需要使用复制赋值运算符:
Class& operator=(const Class& other);
你的类有一个成员,他是一个名为 的指针stored
。Class
复制的实例时:
Class foo( "str" );
Class bar( foo ); // Copy
使用默认的复制构造函数,它将复制类的成员,在这种情况下,它将复制stored
谁是指针,而不是其内容。
这就是为什么,您需要在这里重新定义一个复制构造函数和一个operator=
或复制赋值运算符,例如:
Class::Class( const Class& another )
{
stored = new char[strlen(another.stored) + 1];
strcpy( stored, another.stored );
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Copy the buffer
}
void Class::operator = ( const Class& another )
{
char* temp = new char[strlen(another.stored) + 1];
strcpy( temp, another.stored);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Copy the buffer
delete[] stored;
stored = temp;
}
否则,当第一个实例(比如说)a
被破坏时,当您尝试访问.stored
b
因为您的stored
变量是一个普通的指针(有效的缓冲区地址)。所以当你复制一个对象时,这个指针(地址)被复制到另一个对象。因此,您最终会得到两个指向同一位置(缓冲区)的对象。要获得正确的行为,您需要使用一些智能缓冲区(如 std::vector)或在其中手动写入复制 ctor 和复制缓冲区。
new
以任何方式处理它。