2010-01-12 2 views
8

У меня есть вопрос о следующем коде:Виртуальный деструктор для повышения: неквалифицированные классы?

class MyClass : private boost::noncopyable 
{ 
    public: 

    MyClass() {} 
    virtual ~MyClass() {} 
} 

class OtherClass : private boost::noncopyable 
{ 
    private: 
    MyClass* m_pMyClass; 
} 

Мои мысли, что MyClass не могут быть скопированы с помощью конструкции или назначения. Использование виртуального деструктора необходимо, если я хочу поддерживать вывод классов из MyClass, которые я не хочу поддерживать. Я не собираюсь создавать указатели на этот класс и передавать их.

Мне не нужен синглтон, и я не вижу недостатка в удалении виртуального деструктора.

Должен ли я представить потенциальную проблему, если удалить виртуальный деструктор для класса noncopyable? Есть ли более эффективные методы обработки класса, который не должен быть Singleton, но я хочу только один экземпляр в другом классе и не поддерживать наследование?

+3

Если вы не хотите, чтобы поддерживать наследование, рассмотреть вопрос о внесении конструктор приватным и иметь статический create-function. – Macke

+1

Маркус: Хотя для этого нужны другие вещи, которые он не хочет поддерживать, например, копирование или прохождение указателей (фабрика должна возвращать по значению или возвращать указатель). – 2010-01-12 20:58:02

ответ

13

Нет, вся точка виртуального деструктора является таким образом, что производные классы могут корректно разрушать полиморфно. Если это никогда не будет базовым классом, вам не нужно, чтобы он был виртуальным.

3

Я действительно не поклонник класса boost :: noncopyable в целом. Почему бы просто не объявить конструктор экземпляра класса и оператор присваивания частным образом, а не определить их. Это выполнит одно и то же, и вы можете сорвать виртуальный деструктор.

Boost предоставляет только виртуальный деструктор, так что люди могут передавать объекты boost :: noncopyable полиморфными и все еще ведут себя хорошо. С технической точки зрения, если вы не собираетесь использовать класс полиморфно (вы даже можете его унаследовать), вам действительно не нужен виртуальный деструктор.

+1

Потому что boost :: noncopyable более читабельен, как говорят сами. –

+5

boost :: noncopyable не предоставляет виртуального деструктора – villintehaspam

+1

Считываемость находится в глазу наблюдателя – 2010-01-12 20:57:59

9

Общее правило: если ваш класс имеет виртуальные функции, ему нужен виртуальный деструктор. Если это не так, но все же происходит из базового класса, базовый класс (и, следовательно, ваш класс) может или не может нуждаться в виртуальном деструкторе.

Получение вашего класса от boost::noncopyable на самом деле не считается производным от базового класса. boost::noncopyable больше похож на удобную аннотацию, подкрепленную несколькими объявлениями, которые заставят компилятор обеспечить соблюдение аннотации. На самом деле это не базовый класс в обычном смысле. Никто никогда не попытается передать указатель на ваш класс как указатель или ссылку на boost::noncopyable. И даже если бы они сделали ваш виртуальный деструктор, это не помогло, потому что деструктор boost::noncopyable не является.

И, наконец, как было отмечено в комментарии, вы даже наследуете от boost::noncopyable, так что это даже не наследование на самом деле никого вне класса.

Так что, действительно, не нужно делать его виртуальным деструктором.

+1

Он использует личное наследование, вне класса, он будет отображаться как не наследуемый от 'boost :: noncopyable' –

3

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

Base *pBase = new Derived(); 
delete pBase; 

//if destructor is not made virtual then derived class destructor will never called. 

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

Base *pBase = new Derived(); // will flash error 
1

boost::noncopyable предназначается, чтобы сказать, что вы не хотите копии объекта сделаны. Вы знаете, что это отличается от того, что происходит от объекта.

Совершенно прекрасно избавиться от виртуального деструктора, если вы никогда не извлечете его из объекта. Если вы хотите применить политику «не выводить из этого объекта», there is a way. К сожалению, нет boost::nonderivable для этого.


Как уже упоминалось в ссылке, C++ 11 позволяет объявить класс final:

class MyClass : final private boost::noncopyable { ... }; 
+0

Неработающая ссылка. Меня интересует. – Caduchon

+1

Я обновил ссылку. Спасибо за доклад. –

Смежные вопросы