2017-11-30 8 views

답변

1

은 다음과 비슷한 모습이 될 것입니다

포인터가 아닌 멤버 변수에 대한
#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 연산자를 사용하고 다른 객체가 가지고있는 포인터로 생성합니다.

+0

일반적으로 새 리소스를 설정하기 전에 이전 리소스를 해제해야합니다. 따라서'if (m_someclass && m_someclass! = other.m_someclass) delete m_someclass;를 검사하여 m_someclass를 덮어 씁니다. other.m_someclass! = nullptr 인 경우에만 복사 생성자를 호출하십시오. –

+0

아, 아주 좋은 지적이다. 하지만 널 포인터를 지우는 것이 안전하기 때문에'if (m_someclass)'를 삭제하기 전에 검사 할 필요가 없다고 생각합니다. 또한 각 객체가 m_someclass를 "소유"한다면 두 개의 다른 객체가 동일한 m_someclass를 가질 것이라고 생각하지 않습니다. 하지만 어쨌든 수표를 거기에 넣었습니다. 예외 안전을위한 임시 포인터에서'new SomeClass'를 사용했습니다. 새로운 throw가 발생하면 m_someclass는 동일하게 유지됩니다. 당신이 무슨 생각을하는지 제게 알려주세요. –

+0

소유권이 명확하면 오른쪽 오른쪽. 아직 예외는 아닙니다. 일반적으로 당신은 코드를 나누어서 처음부터 분리하고 던져 버리지 않는 두 번째 부분에 멤버 변수를 설정해야합니다. 이제 m_double si가 덮어 쓰지만 m_someclass가 아닌 상황에 빠질 수 있습니다. 아래로 이동하거나 temp var를 사용할 수 있습니다. 또한 "3의 규칙"을 따르기 위해 수업을 고칠 수 있습니다 –