2009-05-05 4 views
14

У меня есть большой набор унаследованных классов (критериев), которые наследуются от базового класса (критерий). Вот criterion «с КодВиртуальные деструкторы по умолчанию в C++

class criterion 
{ 
public: 
    virtual unsigned __int32 getPriorityClass() const = 0; 
    virtual BOOL include(fileData &file) const = 0; 
    virtual void reorderTree() = 0; 
    virtual unsigned int directoryCheck(const std::wstring& directory) const = 0; 
    virtual std::wstring debugTree() const = 0; 
}; 

Некоторые примеры производных классов от этого:

class fastFilter : public criterion 
{ 
public: 
    void reorderTree() {}; 
    unsigned int directoryCheck(const std::wstring& /*directory*/) const { return DIRECTORY_DONTCARE; }; 
    unsigned __int32 getPriorityClass() const { return PRIORITY_FAST_FILTER; }; 
}; 

class isArchive : public fastFilter 
{ 
public: 
    BOOL include(fileData &file) const 
    { 
     return file.getArchive(); 
    } 
    std::wstring debugTree() const 
    { 
     return std::wstring(L"+ ISARCHIVE\n"); 
    }; 
}; 

Поскольку у меня нет деструктор здесь все, но все же это должно быть базовым классом , мне нужно вставить пустой виртуальный деструктор, т. е. например:

virtual void ~criterion() = 0; 

Если это виртуальное объявление деструктора необходимо, нужны ли все промежуточные классы? То есть для fastFilter выше нужен виртуальный деструктор?

+0

Вышеупомянутый не пустой деструктор. Это деструктор, который также является чистой виртуальной функцией. Это не имеет никакого отношения к тому, чтобы быть пустым, а на самом деле деструктор особенным в том, что он всегда должен иметь определение, даже если он является чисто виртуальным. –

ответ

37

Да - базовому классу нужен виртуальный деструктор, даже если он пуст. Если это не будет сделано, то когда-то delete - производный объект через базовый указатель/ссылку, объекты-члены производного объекта не получат возможность правильно уничтожить себя.

Производные классы не должны объявлять или определять свой собственный деструктор, если им не требуется что-то другое, кроме поведения деструктора по умолчанию.

23

Рекомендация для вставки

virtual ~criterion() {} 

, чтобы избежать удаления выключения проблемы указателя базового класса. В противном случае вы будете утечка памяти, поскольку деструкторы производных классов не будут вызваны.

criterion *c = new fastFilter(); 
delete c; // leaks 
+1

Есть ли причина использовать пустой деструктор над чистым виртуальным? –

+0

Nevermind ... ответил кто-то еще :) –

+1

Не 'виртуальный ~ критерий() noexcept {}' красивее? – user1095108

12

Вам не нужно, чтобы сделать деструктор аннотацию, просто дать ему пустую реализацию:

virtual ~criterion() { } 

Таким образом, вы не обязаны его реализовать в каждом дочернем классе, но все-таки каждый из они будут иметь (унаследованный) виртуальный деструктор.

7

Одно небольшое изменение от того, что другие уже ответили:

Вместо

virtual void ~criterion() = 0; 

требуемой версии:

virtual ~criterion() {} //Note: Removed void as destructors not allowed 
          // a return type 

Чтобы узнать больше о виртуальном деструкторе взглянуть на это link from FAQ When should my destructor be virtual?