2016-10-08 2 views
9

나는 정말로 이해하지 못하는 것에 빠지면서 shared_ptr 's와 enable_shared_from_this를 사용하여 조금 놀고 있었다.std :: enable_shared_from_this; public 대 private

class shared_test : std::enable_shared_from_this<shared_test> { 
public: 
    void print(bool recursive) { 
     if (recursive) { 
      shared_from_this()->print(false); 
     } 

     std::cout << "printing" << std::endl; 
    } 
}; 

이 클래스는 표준을 확장하고 있습니다 : 개인적으로 enable_shared_from_this : 내 첫 번째 시도에서

나는 이런 식으로 뭔가를 건설했다. 이것은 분명히 다음과 같이 실행하기 때문에 많은 차이를 만듭니다 :

int main() { 
    auto t(std::make_shared<shared_test>()); 
    t->print(true); 
    return 0; 
} 

은 bad_weak_ptr 예외를 throw합니다. 클래스 정의를 std :: enable_shared_from_this에서 공개적으로 공개하는 것처럼 여기는 그냥 find를 실행합니다.

왜 그런가, 내가 여기서 무엇을 놓칠까요? shared_test 클래스의 '외부 세계'는 이것이 공유를 가능하게한다는 것을 알 필요가 없기 때문에 개인 상속을 위해 작동하도록하는 방법이 없습니까? (최소한, 당신이 저에게 묻는다면, 또는 다시 무언가를 놓칠 수 있습니까?)

답변

6

왜 여기에 놓칠 수 있습니까?

shared_from_thisenable_shared_from_this에 대한 shared_ptr 클래스를 보유하고 알고 있습니다 확인하십시오. STL 구현에서는 weak_ptr이고 다른 구현이 가능합니다. 비공개로 상속하면 클래스 외부에서 기본 클래스의 속성에 액세스 할 수 없습니다. 사실 상속받은 사실을 이해하는 것도 불가능합니다. 따라서 make_sharedenable_shared_from_this에 적절한 필드를 설정하지 않고 일반적인 shared_ptr 초기화를 생성합니다.

이 제대로 초기화되지 않았으므로 make_shared이 아닌 예외가 발생하지만 shared_from_this은 예외입니다.

그리고는 ... 그것은이에서 공유 활성화시키는 것을 알 필요가없는 shared_test 클래스의 '외부 세계'이후, 개인 상속을 위해 일 할 수있는 방법하지가

아니요. 외부 세계는 오브젝트가 shared_ptr과의 특별한 관계를 가지고 있어야 제대로 작동한다는 것을 알아야합니다.

+0

여전히 오류는 개인 액세스 컴파일 오류가 아니라 런타임 오류입니다. 내가 생각할 수있는 다른 모든 경우에는, 레이아웃, 결단, ...에는 아무런 차이가 없다. 액세스 제어는 #define private public이 동일한 오브젝트 파일을 제공하는 지점까지 마지막으로 독립적으로 수행됩니다. –

+0

@JohanLundberg '외부 세계'에는 개인 상속과 상속이 (논리적 인) 차이가 없습니다. private 상속은'is_base_of , shared_test>'가 거짓이라는 것을 의미한다. 이것은 shared_ptr 생성자가 생성 한 코드를 제어하는 ​​컴파일 타임 테스트이다. – Oktalist

+0

@Oktalist. 고마워요 - 따라와. 내 의견에 쓴 것은 분명히 상속을위한 것이 아닙니다. –

0

설명서에 따르면 "shared_from_this"멤버 함수의 액세스 가능성을 공개적으로 상속해야합니다.

공공 *의 소유권이 (공유하는 shared_ptr의를 반환 CPP 기준에서 http://en.cppreference.com/w/cpp/memory/enable_shared_from_this

shared_from_this -

"공개적으로 표준 : enable_shared_from_this에서 상속는 멤버 함수 shared_from_this와 유형 (T)를 제공합니다" 멤버 함수)

+0

귀하의 답변은 실제로 질문에 새로운 내용을 추가하지 않습니다 : shared_from_this는 공개적으로 상속되어야합니다. 흥미로운 부분은 그러한 제한이있는 이유입니다. –

+0

"enable_shared_from_this"는 "shared_from_this"가 아닌 ..... 상속되어야합니다. 그리고 "shared_from_this"는 "* this"포인터를 반환하는 기본 클래스 내부의 함수입니다. 클래스 이름과 함수 이름 사이에 "enable_"이라는 단어가 추가되어 있음을 유의하십시오. – Naidu

+0

그리고 알다시피 ... Base 클래스의 보호 된 멤버 및 공용 멤버는 Derived 클래스의 비공개 멤버가됩니다. 따라서 파생 클래스에서 private 클래스이므로 Base 클래스의 멤버는 파생 클래스 개체를 통해 다른 클래스에서 액세스 할 수 없습니다. – Naidu

5

shared_test 클래스의 '외부 세계'는 그 (것)들을 알 필요가 없기 때문에 개인 상속을 위해 작동하게하는 방법이 없습니다. 이것으로부터 공유를 가능하게하는 것입니다.

shared_ptr 그 자체는 '외부 세계'의 일부입니다. shared_ptr 생성자는 enable_shared_from_this 구현의 private weak_ptr 멤버를 초기화하기 위해 해당 객체가 가리키는 shared_test 객체의 기본 클래스 하위 객체 enable_shared_from_this에 액세스 할 수 있어야합니다.

관련 문제