2014-06-15 6 views
4

다형성에 대한 모든 예제에서 기본 클래스의 소멸자는 virtual이며 빈 몸체로 정의됩니다.기본 클래스 소멸자의 정의는 필요하지 않습니까?

나는이 문제에 대해 내 머리를 터지려고 노력하고있다. 왜 그것은 비어있는 몸이어야 하는가? 메소드가 virtual으로 선언되었지만 emtpy 본문으로 정의되지 않은 경우 왜 작동하지 않습니까? 그렇다면 기본 소멸자가 구현하지 않겠습니까? 또는 그것이 virtual으로 선언되고 있다는 사실은 심지어 기본 정의를 강요하고 명시 적으로 본문을 정의하도록 강제합니까?

이 무슨 뜻입니다 :

class A { 
public: 
    virtual void f(); 
    virtual ~A() {} 
} 

class B : public A { 
public: 
    ~B() { 
     // destroy whatever 
    } 
} 

~A() 단지 정의없이 본 virtual ~A();과 같이 선언 할 수 없습니다?

또한 추상 클래스에서 (빈 몸체로) 정의해야하는 이유는 무엇입니까? 이 virtual ~A() = 0과 같은 추상 클래스의 destuctor를 선언하려고 시도했지만 컴파일러가 그렇게하지 못하게했습니다.

+0

여기서 토론을 참조하십시오. 이것은 가상 소멸자 동작에 대한 매우 자세한 설명을 제공합니다. https://stackoverflow.com/questions/461203/when-to-use-virtual-destructors – CoryKramer

+0

@Cyber ​​저 게시물을 이미 보았습니다. – dabadaba

답변

7

~A() 단지 정의없이 본 virtual ~A();과 같이 선언 할 수 없습니다?

정의되지 않은 기능을 호출 할 수 없기 때문에. 그처럼 간단합니다. 을 지정하지 않으면 소멸자가 암시 적으로 컴파일러 으로 정의됩니다. 그러나 선언을 자신에게 제공하면 컴파일러는 더 이상 정의을 제공하지 않습니다. C++ 11에서 명시 적으로 기본 정의를 제공 할 수 있습니다.

또한
virtual ~A() = default; 

, 왜 추상 클래스에서 (빈 몸으로) 그렇게 정의 할 수 있습니까? 이 virtual ~A() = 0과 같은 추상 클래스의 destuctor를 선언하려고 시도했지만 컴파일러가 그렇게하지 못하게했습니다.

같은 이유. 소멸자가 호출되는 한 다른 함수와 마찬가지로 정의가 있어야합니다. 일반적으로 순수 가상 함수는 호출되지 않지만 소멸자는 예외입니다. 정의를 제공해야합니다.

class A { 
// ... 
    virtual ~A() = 0; // declare destructor as pure virtual 
}; 
// ... 
A::~A() {} // define destructor 
+0

보통 'A'로부터 상속받은 클래스에서 소멸자를 제공하는 것은'virtual ~ A() = 0'에 대한 정의를 제공해야한다고 가정하지만 소멸자를 덮어 쓸 수 없기 때문에 소멸자를 확장 할 수 없으므로 그렇지 않습니다. – pmr

+0

추상 클래스의 경우 소멸자 정의가 필요합니다. 이해합니다. 그건 말이되지 않습니다. 클래스가 클래스의 인스턴스가 없으므로 클래스가 추상화되면 아무 객체도 소멸 될 필요가 없으므로 소멸자가 필요하지 않습니다. – dabadaba

+0

@dabadaba 객체가 파기되면, 기본 클래스가 추상 클래스 인 경우에도 기본 클래스 소멸자가 호출됩니다. – Brian

1

소멸자는 개체가 파괴 될 때 호출되기 때문에 본문이 있어야합니다. 파생 된 객체가 파괴 될 때마다 마지막 단계는 기본 클래스의 소멸자를 호출하는 것입니다. 본문이 없으면 링커는 해당 소멸자의 정의를 찾을 수 없으며 정의가없는 일반 함수처럼 호출이 실패합니다.

그것은 전적으로 가능 순수 가상 소멸자에게 몸주고 (필요한 몇 가지 모호한 사용 금지)입니다 :

class Foo { 
public: 
    virtual ~Foo() = 0; 
}; 

Foo::~Foo() {} //pre-C++11 
Foo::~Foo() = default; //for an empty body with some benefits; C++11 and on 
0

전혀 소멸자를 선언하지 않으면 컴파일러를 생성하지만 당신은 하나를 선언하는 경우 당신은뿐만 아니라 그것을 정의 할 필요하거나 해결되지 않은를 얻을 수 있습니다, 그래서 그것은 자동 생성을 억제 - 링크시 기호 오류.파생 때문에

virtual ~Foo() = default; 

기본 클래스의 소멸자가 어떻게 든 (비어 경우에도) 정의 할 수 있습니다

C++ 11에서

, 당신은 가상으로 소멸자를 선언하지만 여전히 구현을 컴파일러를 생성 할 수 있습니다 클래스의 소멸자는 결국 암묵적으로 호출합니다. 순수 가상 소멸자를 갖는 것은 이치에 맞지 않습니다. 파생 클래스는 자신의 소멸자를 정의 할 수 있지만 기본 클래스의 소멸자를 정의 할 수 없습니다.

관련 문제