2016-08-16 3 views
0

this을 사용하는 데 어려움이 있습니다. 파생 클래스를 조각화 한 것 같습니다. 이 예제는 내 문제를 설명하는 데 도움이 될 것입니다.이 조각을 사용하여 내 개체

class A 
{ 
    A() { 
     OtherClass(*this); 
    } 

    virtual doSomething() = 0; 
} 

class B : public A 
{ 
    B() : A() {} 

    doSomething() override { 
     std::cout << "Hi!" << std::endl; 
    } 
} 

class OtherClass() 
{ 
    OtherClass(A &a) { 
     a.doSomething(); 
    } 
} 

몇 가지 조사 후에는 사용 *this 슬라이스 클래스 B처럼 보인다. 그리고 OtherClassA에서 순수 가상 메서드를 호출합니다. 내가 틀렸다? B 클래스 초기화 후 OtherClass(*this)을 작성해야합니까?

답변

2

A의 생성자는 A의 순수 가상 메서드를 호출하는 OtherClass의 생성자를 호출합니다.

불행히도이 가상 메서드를 구현하는 A의 하위 클래스가 아직 구성되지 않았으므로 결과는 정의되지 않은 동작입니다.

주의 사항 : 수퍼 클래스는 서브 클래스보다 먼저 생성됩니다. B이 구성되기 전에 (순수 가상 메서드를 구현할 때) 수퍼 클래스 인 A을 완벽하게 구축해야합니다. 그 과정의 일부로서 물론 A의 생성자가 호출됩니다.

+0

'수퍼 클래스보다 하위 클래스가 생성됩니다'. 그게 맞습니까? 기본 (수퍼) 클래스는 파생 (하위) 클래스보다 먼저 생성됩니다. –

+0

어, 수정했습니다 ... –

2

따라서 슬라이싱 문제가 아닙니다.

생성자/소멸자에서 가상 메서드는 가상으로 호출되지 않습니다.

객체가 완전히 구성되지 않았거나 부분적으로 소멸되었다는 합리적입니다. this 포인터는 파생 클래스를 가리 키지 않으며 현재 생성/삭제 된 클래스 (이 경우 A)에만 포인터를 지정합니다.

+0

실제로 'OtherClass'에서'A :: doSomething' *가 가상으로 호출됩니다. 그러나 객체 동적 유형이 아직 조정되지 않았으므로 ('A'의 시작자가 끝나지 않고 객체의 시작점이 'A'의 vtable까지) 순수 가상이 호출됩니다. – StoryTeller

+0

@StoryTeller : constructor/destructor의'this-> doSomething()'은'B :: doSomething()'대신에'A :: doSomething()'(순수한 가상 호출 인 OP의 경우)과 동일합니다 컴파일러가 * "modified"* vtable (다이아몬드 계층 구조에 대해 생각해보십시오)로 전달하도록 선택하는 경우). – Jarod42

+0

그러나 이것은'this-> doSomething()'이 아닙니다. 'anotherObj-> doSoemthing()'입니다. – StoryTeller

관련 문제