2016-09-19 8 views
2

가정하자 내가 가진 클래스 Bla의 다른 개체에 대한 포인터입니다 단일 멤버 변수 "는이"Foo : 내가 처리하려면 어떻게포인터가있는 객체의 return-by-value를 처리하는 방법은 무엇입니까?

struct Foo { 
    Bla *bla; 

    Foo() { 
     this->bla = new Bla(); 
    } 
    ~Foo() { 
     delete this->bla; 
    } 
}; 

를 반환별로 가치와 같은 객체?

Foo make_foo() { 
    return Foo(); 
} 

이것은 새로운 FooBar에서, Bla 객체를 내부 포인터의 사본을 포함하여 생성 된 Foo 개체의를 복사 반환 한 다음 로컬 객체를 자폭 그것으로 만듭니다. 따라서, 다음 코드는 실패

Foo f = make_foo(); 
std::cout << f.bla << std::endl; 

이 일이 일반적으로 생각 빈약 한 설계인가?

copy constructor을 제공해야합니까? 이 경우,보다 복잡한 오브젝트 트리를 깊이 복사하면 성능에 심각한 영향을 줄 수 있습니다.

move constructor을 제공해야합니까? bla 포인터를 제대로 처리 할 수 ​​있습니까?

+0

왜 코드가 실패했다고 생각합니까? 'bla'도 복사됩니다 (포인터 자체). [3의 규칙은 무엇입니까?] (http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three)를보고 싶을 수도 있습니다. – songyuanyao

+1

복사 생성자에 대한 [copy-on-write] (http://stackoverflow.com/questions/628938/what-is-copy-on-write)도 있으므로 성능에 미치는 영향을 줄일 수 있습니다. ''shared_ptr' (http://en.cppreference.com/w/cpp/memory/shared_ptr)를 사용하여 참조 카운트 된 일부 복사본을 공유 한 다음 실제로 복사 할 때까지 전체 복사본을 만들지 마십시오. 데이터를 수정해야합니다. –

답변

2

클래스가 동적 메모리를 할당하고 소멸자에서 메모리를 할당 해제 했으므로 The Rule of Three을 따르십시오. 복사본 생성자 및 복사 할당 연산자를 제공하십시오.

이동 의미론을 이해하거나 rvalue 참조를 사용하려는 경우 이동 생성자를 제공하고 할당 연산자도 함께 이동하십시오. 자세한 내용은 Rule-of-Three becomes Rule-of-Five with C++11?을 참조하십시오.

+0

* 규칙 3 *에 큰 참조, 감사합니다! – Jens