0

https://stackoverflow.com/a/3278636/462608

Class::Class( const char* str )
{
    stored = new char[srtlen( str ) + 1 ];
    strcpy( stored, str );
}

在这种情况下,存储成员的成员方式复制不会复制缓冲区(只会复制指针)

但是这里的内存是由new. 那为什么仍然说只有指针会被复制而不是整个缓冲区呢?

4

3 回答 3

4

在您的班级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);
于 2013-09-04T06:53:33.823 回答
1

你的类有一个成员,他是一个名为 的指针storedClass复制的实例时:

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被破坏时,当您尝试访问.storedb

于 2013-09-04T06:59:10.637 回答
0

因为您的stored变量是一个普通的指针(有效的缓冲区地址)。所以当你复制一个对象时,这个指针(地址)被复制到另一个对象。因此,您最终会得到两个指向同一位置(缓冲区)的对象。要获得正确的行为,您需要使用一些智能缓冲区(如 std::vector)或在其中手动写入复制 ctor 和复制缓冲区。 new以任何方式处理它。

于 2013-09-04T06:55:59.273 回答