그래서 ... std::string
을 사용하여 솔루션이 제공되었지만 멤버 변수를 그대로 유지하면서 다른 솔루션을 제공하겠습니다.
문제는 이것입니다. (1) 방법 Player& Player::operator=(const Player&)
가 호출에서
Player p1("Bob"); // Okay
Player p2("Annie"); // Okay
p2 = p1; // Oops! (1)
Player p3(p1); // Oops! (2)
: 당신이 어딘가에이 코드가 있다고 가정. 당신이 제공하지 않았기 때문에, 컴파일러는 당신을 위해 하나를 생성합니다. 그럴 때 모든 멤버 변수를 복사 할 수 있다고 가정합니다. 이 경우 Player::name
및 Player::length
을 복사합니다. 그래서 우리는 p1.name == p2.name
입니다. 이제 p2
의 소멸자가 호출되면 p2.name
이 가리키는 할당 된 메모리가 삭제됩니다. 그런 다음 소멸자 p1
이 호출되면 과 동일한 메모리가 삭제됩니다 (p1.name == p2.name
부터)! 그건 불법입니다.
이 문제를 해결하려면 할당 연산자를 직접 작성할 수 있습니다.
Player& Player::operator = (const Player& other)
{
// Are we the same object?
if (this == &other) return *this;
// Delete the memory. So call the destructor.
this->~Player();
// Make room for the new name.
length = other.length;
name = new char[length + 1];
// Copy it over.
for (unsigned int i = 0; i < length; ++i) name[i] = other.name[i];
name[length] = '\0';
// All done!
return *this;
}
(2)에서 동일한 문제가 발생합니다. 당신은 복사 생성자가 없으므로 컴파일러가 생성자를 생성합니다. 또한 모든 멤버 변수를 복사 할 수 있으므로 소멸자가 호출되면 동일한 메모리를 다시 삭제하려고 시도합니다. 당신이 불구하고 std::string
를 사용해야 하루의 끝에서
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];
}
:이 문제를 해결하려면, 또한 복사 생성자를 작성합니다.
클래스가 [Rule of Three] (http://stackoverflow.com/questions/4172722)를 따르고 있습니까? 그렇지 않다면 동일한 버퍼를 두 번 삭제할 가능성이 있습니다.특히 포인터 - 저글링 기술을 연습하고 싶지 않으면'std :: string'을 사용하여 동적 메모리를 올바르게 관리하십시오. –
문제를 일으키는 특정 코드가 무엇이라는 것을 어떻게 알 수 있습니까? – Jon
관련 : [규칙 5] (http://stackoverflow.com/questions/4782757/rule-of-three-becomes-rule-of-five-with-c11) – Deduplicator