딥 복사를 수행하기 위해 할당 연산자 오버로딩을 사용하려하지만 올바른 방법을 찾을 수 없습니다. 나는 클래스 컴퓨터를 가지고 있으며 그것을 클래스 랩탑 컴퓨터에 복사 할 때 사용할 필요가있다.C++에서 할당 연산자 오버로드를 구현하는 방법은 무엇입니까?
답변
은 다음과 비슷한 모습이 될 것입니다
포인터가 아닌 멤버 변수에 대한#include <algorithm>
class SomeClass {};
class AnotherClass {};
class Computer
{
public:
Computer() :
m_someclass(new SomeClass()),
m_double(0.0)
{
}
virtual ~Computer()
{
delete m_someclass;
}
Computer(const Computer& other) :
m_someclass(new SomeClass(*other.m_someclass)),
m_double(other.m_double)
{
}
Computer& operator=(const Computer& other)
{
if (this != &other)
{
Computer tmp(other);
swap(tmp);
}
return *this;
}
void swap(Computer& other) noexcept // or throw() for before c++11
{
std::swap(m_someclass, other.m_someclass);
std::swap(m_double, other.m_double);
}
private:
SomeClass* m_someclass;
double m_double;
};
class Laptop : public Computer
{
public:
Laptop() :
m_anotherclass(new AnotherClass()),
m_int(0)
{
}
virtual ~Laptop()
{
delete m_anotherclass;
}
Laptop(const Laptop& other) :
Computer(other),
m_anotherclass(new AnotherClass(*other.m_anotherclass)),
m_int(other.m_int)
{
}
// Create a Laptop object from a Computer object
explicit Laptop(const Computer& other) :
Computer(other),
m_anotherclass(new AnotherClass()),
m_int(0)
{
}
Laptop& operator=(const Laptop& other)
{
if (this != &other)
{
Laptop tmp(other);
swap(tmp);
}
return *this;
}
// Assign a laptop object from a computer object.
Laptop& operator=(const Computer& other)
{
if (this != &other)
{
Laptop tmp(other);
swap(tmp);
}
return *this;
}
void swap(Laptop& other) noexcept // or throw() for before c++11
{
Computer::swap(other);
std::swap(m_anotherclass, other.m_anotherclass);
std::swap(m_int, other.m_int);
}
private:
AnotherClass* m_anotherclass;
int m_int;
};
int main()
{
Computer computer;
// Construct a new Laptop object by copying data from a Computer object
Laptop laptop1(computer);
// Assign Computer data in Laptop to that of a Computer object
Laptop laptop2;
laptop2 = computer;
}
, 당신은 단지 연산자 표준 복사를 수행 =. 객체가 소유 한 포인터 멤버 변수의 경우 new 연산자를 사용하고 다른 객체가 가지고있는 포인터로 생성합니다.
일반적으로 새 리소스를 설정하기 전에 이전 리소스를 해제해야합니다. 따라서'if (m_someclass && m_someclass! = other.m_someclass) delete m_someclass;를 검사하여 m_someclass를 덮어 씁니다. other.m_someclass! = nullptr 인 경우에만 복사 생성자를 호출하십시오. –
아, 아주 좋은 지적이다. 하지만 널 포인터를 지우는 것이 안전하기 때문에'if (m_someclass)'를 삭제하기 전에 검사 할 필요가 없다고 생각합니다. 또한 각 객체가 m_someclass를 "소유"한다면 두 개의 다른 객체가 동일한 m_someclass를 가질 것이라고 생각하지 않습니다. 하지만 어쨌든 수표를 거기에 넣었습니다. 예외 안전을위한 임시 포인터에서'new SomeClass'를 사용했습니다. 새로운 throw가 발생하면 m_someclass는 동일하게 유지됩니다. 당신이 무슨 생각을하는지 제게 알려주세요. –
소유권이 명확하면 오른쪽 오른쪽. 아직 예외는 아닙니다. 일반적으로 당신은 코드를 나누어서 처음부터 분리하고 던져 버리지 않는 두 번째 부분에 멤버 변수를 설정해야합니다. 이제 m_double si가 덮어 쓰지만 m_someclass가 아닌 상황에 빠질 수 있습니다. 아래로 이동하거나 temp var를 사용할 수 있습니다. 또한 "3의 규칙"을 따르기 위해 수업을 고칠 수 있습니다 –
정확하게하고 싶은 코드 샘플을 보내 주시면 감사하겠습니다. –