2014-06-15 5 views
1

우리가이 같은 순수 가상 소멸자, 사용할 수있는 것으로 알려져있다 : 표준이 10.4 [class.abstract] p2소멸자의 순수 가상 함수 호출이 UB 인 경우 왜 순수 가상 Desrtuctor를 사용할 수 있습니까?

순수 가상 함수라고 불리는 경우에 ...에만 정의 할 필요가 있기 때문에

struct A { 
    virtual ~A() = 0; 
}; 
A::~A() {} 

struct B : A {}; 

을 (12.4 [class.dtor])

그리고 나중에 12.4 [class.dtor] p9

소멸자는 가상 (10.3) 또는 순수 가상 (10.4)로 선언 할 수 있습니다. 해당 클래스의 객체 나 파생 된 클래스가 프로그램에 생성되면 소멸자가 정의됩니다.

위의 코드를 완벽하게 유효하다는 것을 의미

-A::~A 그것이 정의, 가상 순수 할 수있다, B::~B 암시 A::~A를 호출합니다.

지금까지 그렇게 좋았습니다.
그리고 나는 10.4 [class.abstract] p6 읽기 :

멤버 함수가 생성자 (또는 소멸자) 추상 클래스에서 호출 할 수 있습니다; 그러한 생성자 (또는 소멸자)로부터 생성 (또는 소멸)되는 객체에 대해 직접 또는 간접적으로 순수 가상 함수에 가상 호출 (10.3)을하는 효과는 정의되지 않습니다.

하지만 정확히 여기서 우리가하는 것은 - 우리는 소멸자에서 순수 가상 함수 A::~A을 호출합니다.

그래서 어떤 모순이 있습니까?

+0

소멸자는 특별한 경우입니다. 순수 가상이라 할지라도 소멸자는 여전히 (표준에 따라) 본문을 가지고 있어야하기 때문입니다. 정의되지 않은 부분은 순수 가상 멤버 함수 (정의가 없을 수도 있음)에 적용됩니다. – StoryTeller

답변

3

수축이 없습니다.

가상 소멸자 A을 소멸자 B에서 호출합니다. A 소멸자가 B의 구성원이 아닙니다.

표준 친구 지정자 ( 11.3)로 선언하는 제외

기능은 클래스의 정의에 선언 9.3

멤버 함수는 해당 클래스의 멤버 함수를 호출 §

표준은 가상 전화가있을 때 정의되지 않은 동작이 있음을 나타냅니다 추상화 클래스 소멸자/생성자 (귀하의 경우에는 A 클래스)는 순수 가상 멤버 함수입니다.

[...] 멤버 함수가 추상적 클래스 [의 생성자 (또는 소멸자)에서 호출 할 수 있습니다 ...];

견적은 소멸자에 대해 말한다 : 당신이 (가상 호출) 순수 가상 메서드를 호출 할 경우

  1. 당신은으로부터 추상 클래스
  2. 의 소멸자에서 를 멤버 함수를 호출 할 수 있습니다 이 추상 클래스의 소멸자에는 정의되지 않은 동작이 있습니다.
+0

그리고'B'가 추상 클래스일까요? 그러면 UB가 될까요? – Abyx

+0

아니, 그 시점에 대한 명확하지 않았다, 내 편집을 참조하십시오. – quantdev

-2

가상 전화 (10.3 [class.virtual])이있는 경우 UB가 발생합니다.

가상 호출 (10.3)을 순수 가상 함수에 적용한 결과는 정의되지 않았습니다.

하지만 10.3 [class.virtual] P15 스코프 연산자 (5.1)와

명시 자격 가상 전화 메카니즘을 억제하는 것을 말한다.

암시 적 소멸자 호출에 명시 적 자격이있는 것으로 보입니다.
적어도 컴파일러는 가상 전화를 확실히하지 않습니다.