Имеется кусок кода:

[-]
View Code C++
#include <string>

class Base {
public:
    Base(void) {}
    virtual ~Base(void) throw() {}
};

class Derived : public Base {
public:
    ::std::string s;
};

int main(int, char**)
{
    return 0;
}

При компиляции в GCC выдает интересную ошибку:

[-]
View Code Bash
g++ test.cpp
test.cpp:9: error: looser throw specifier for ‘virtual Derived::~Derived()
test.cpp:6: error:   overriding ‘virtual Base::~Base() throw ()

Самое интересное, что если сделать Derived::s типа, например, int, то ошибка исчезнет.

В чем же дело?

Во втором случае компилятор генерирует автоматический деструктор с сигнатурой virtual Derived::~Derived() throw(), в первом — просто virtual Derived::~Derived(). Почему же так происходит? Как оказалось, всё просто (отвлекусь: вспомнил старый универский анекдот: стоит профессор у доски и говорит: "Как бы это доказать? Или это очевидно?" Через три часа возвращается уставший студент с толстой распечаткой и говорит: "Действительно очевидно."). На самом деле, при генерации деструктора по умолчанию компилятор рассматривает сигнатуры деструкторов всех статических (не в плане static, а в плане "не динамических") членов класса, и выбирает такую сигнатуру, которая является пересечением всех рассмотренных сигнатур. Дело в том, что деструктор ::std::basic_string не имеет спецификации throw(), и поэтому наиболее совместимым является генерация автоматического деструктора без спецификации throw(). Расчет здесь прост: если компилятор сгенерирует деструктор со спецификацией throw(), а деструктор ::std::basic_string бросит исключение, то это будет нарушением спецификации и, следовательно, будет очень плохо (вообще, на мой взгляд, кидаться исключениями в деструкторе — дурной тон).

Поэтому правильные деструкторы приходится в таких случаях прописывать руками…

Добавить в закладки
  • del.ici.ous
  • Digg
  • Furl
  • Google
  • Simpy
  • Spurl
  • Y! MyWeb
  • БобрДобр
  • Мистер Вонг
  • Яндекс.Закладки
  • Текст 2.0
  • News2
  • AddScoop
  • RuSpace
  • RUmarkz
  • Memori
  • Закладки Google
  • Писали
  • СМИ 2
  • Моё Место
  • Сто Закладок
  • Ваау!
  • Technorati
  • RuCity
  • LinkStore
  • NewsLand
  • Lopas
  • Закладки - I.UA
  • Connotea
  • Bibsonomy
  • Trucking Bookmarks
  • Communizm
  • UCA

Связанные записи

22
Май
2008

Комментарии к статье «GCC и throw-спецификация у автоматически сгенерированного виртуального деструктора»  »

К статье «GCC и throw-спецификация у автоматически сгенерированного виртуального деструктора» комментариев пока нет. Не хотите ли стать первым?

Подписаться на RSS-ленту комментариев к статье «GCC и throw-спецификация у автоматически сгенерированного виртуального деструктора» Trackback URL: http://blog.sjinks.org.ua/uncategorized/156-gcc-throw-specification-in-virtual-destructor/trackback/

Оставить комментарий к записи «GCC и throw-спецификация у автоматически сгенерированного виртуального деструктора»

Вы можете использовать данные тэги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Оставляя комментарий, Вы выражаете своё согласие с Правилами комментирования.

Подписаться, не комментируя