因此...已经提供了使用std::string
的解决方案,但让我给出另一种解决方案,保持您的成员变量不变。
问题是这样的。假设你有这样的代码的地方:
Player p1("Bob"); // Okay
Player p2("Annie"); // Okay
p2 = p1; // Oops! (1)
Player p3(p1); // Oops! (2)
在(1),该方法Player& Player::operator=(const Player&)
被调用。既然你没有提供,编译器会为你生成一个。当它这样做时,它只是假定它可以复制所有成员变量。在这种情况下,它复制了Player::name
和Player::length
。所以,我们有p1.name == p2.name
。现在调用p2
的析构函数时,将删除p2.name
指向的已分配内存。然后当调用p1
的析构函数时,相同的内存将被删除(因为p1.name == p2.name
)!这是违法的。
要解决这个问题,你可以自己写一个赋值操作符。 (2),发生同样的问题。您没有复制构造函数,因此编译器会为您生成一个。它也会假设它可以复制所有的成员变量,所以当析构函数被调用时,它们会尝试再次删除相同的内存。为了解决这个问题,也写了拷贝构造函数:
Player::Player(const Player& other)
{
if (this == &other) return;
length = other.length;
name = new char[length + 1];
for (unsigned int i = 0; i < length; ++i) name[i] = other.name[i];
}
在这一天结束时,你应该使用虽然一个std::string
。
该类是否遵循[Rule of Three](http://stackoverflow.com/questions/4172722)?如果没有,那么你很可能会删除两次相同的缓冲区。使用'的std :: string'正确地管理动态内存给你,除非你特别想练习指针杂耍技能。 –
你怎么知道它是引起问题这个特殊的代码? – Jon
相关:[五规则(http://stackoverflow.com/questions/4782757/rule-of-three-becomes-rule-of-five-with-c11) – Deduplicator