2017-02-22 6 views
0

호기심에서 벗어난 나는 컴파일러가 나에게 스택 오버 플로우로 끝나는 무한 루프를 호출하는 대신 경고를 주는지 또는 아래에있는 예제와 같은 것을 시도했다. 아마도 정상적인 함수 나 메서드를 호출하는 것과는 다른 동작이있을 것이라고 생각했습니다. 하지만 그렇지 않습니다. 거기에 대한 특별한 설명이 있습니까 아니면 난 그냥 명시 적으로 this 연산자를 사용하여 기본 클래스 소멸자를 호출 오전 이후 정상적인 함수 호출로 처리됩니다?컴파일러는 파생 된 소멸자에서 기본 클래스 소멸자 호출을 어떻게 처리합니까?

예 :

class A { 
    virtual ~A(); 
}; 

class B : A { 
    virtual ~B() { this->~A(); } 
}; 
+2

'virtual void ~ A();'- 이것은 컴파일해서는 안되며, 소멸자는 아무 것도 반환하지 않으며 일반적인 메소드 이름에는 tilda를 포함 할 수 없습니다. – yeputons

+0

@yeputons right, sry, typo –

+4

'~ A()'를 두 번 호출하여 정의되지 않은 동작이 발생합니다 ('B()'의 시체가 끝나면 암시 된 호출이 있기 때문에) –

답변

2

는 @ M.M의 코멘트를했다. 소멸자를 두 번 호출합니다. 이는 정의되지 않은 동작이며 사용자가 관찰 한 동작을 포함하여 아무 것도 일어나지 않을 수 있습니다.

은 (실제로, 그 소멸자 호출의 가능성이 가장 높은 사람은 이후의 소멸자가 더 이상 가장 파생 된 개체에 갈 호출을 의미 객체의 vptr에서 수정합니다.하지만 그건 그냥 추측입니다.)

올바른 일을 할일은 소멸자를 수동으로 호출하지 않는 것입니다.

+1

C++ 14 [class.dtor]/15 (특히'virtual'은 중요하지 않기 때문에) non-trivial 소멸자를 가진 클래스의 경우 두 번째 소멸자 호출이 UB라고 명시하는 절입니다. –

0

파생 클래스 가상 소멸자를 호출하면 기본 클래스 소멸자가 호출됩니다. 그러나 그 반대는 아닙니다.

1

파생 클래스의 가상 소멸자는 항상 부모 클래스 소멸자를 재귀 적 순서로 호출하여 가장 "조상의"기본 클래스 소멸자가 호출되고 두 번째로 가장 "조상의"소멸자가 호출됩니다. 아이가 GrandParent로부터 상속받은 부모로부터 상속 받았다고 상상해보십시오. Child 클래스의 소멸자는 실제로 GrandParent의 소멸자를 호출 한 다음 부모의 소멸자를 호출 한 다음 Child의 소멸자를 호출합니다.

실제로 파생 클래스 생성자는 동일한 재귀 순서로 부모 클래스 생성자를 호출합니다. "레이어 케이크"와 같은 파생 클래스를 상상해야합니다. 상속 인스턴스마다 객체에 레이어를 추가합니다. 그래서 Child 클래스는 3 개의 레이어 {GrandParent, Parent, Child}를 가지며, 각 레이어의 생성/파기는 해당 클래스에 의해 처리됩니다.

시도하고있는 것은 부모 소멸자를 두 번 호출하려고 시도하는 것이 좋지 않습니다. 일반적으로 사용자가 new 연산자를 오버로드 한 경우를 제외하고는 소멸자를 명시 적으로 호출 할 필요가 없습니다. Is calling destructor manually always a sign of bad design?