Здравствуйте, comer, Вы писали:
C>Понятное дело что такой вызов не приветствуеться. Но, проведем эксперимент на разных компиляторах.
C>C>// test.cpp
C>struct A
C>{
C> ~A() { F(); }
C> virtual void F() = 0;
C>};
C>struct B: A
C>{
C> void F() {}
C>};
C>int main()
C>{
C> B b;
C> return 0;
C>}
C>
C> ...
C>Ага, а тут это всего лишь сообщение. Но дальше больше. VC 7.0. Компилируем, все хорошо (может какую то галочку забыл нажать в свойствах компиляции?). А вот линкер ругаеться, говорит:
C>C>test.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall A::F(void)" (?F@A@@$$FUAEXXZ)
C>
C>Спрашиваеться, а почему линкер ищет эту абстрактную функцию? Я понял бы другое сообщения об ошибке, но не такое.
Потому что компилятор соображает, что вызов виртуальной функции 'F()' (как и любой другой виртуальной функции) из деструктора класса 'A' совсем не обязательно делать виртуально. Так как уже на стадии компиляции соврешенно ясно, что вызваться будет именно функция 'A::F()', компилятор в целях оптимизации генерирует прямой (невиртуальный) вызов именно функции 'A::F()' из деструктора класса 'A', взваливая задачу связывания этого вызова на хрупкие плечи линкера. Линкер, разумеется, связать этот вызов не может, ибо тела у функции 'A::F()' нет. Отсюда и сообщение об ошибке.
Я думаю, что если бы ты добавил в свой код определение функции 'A::F()', то VC7.0 молча бы скомпилировал этот код.
struct A
{
~A() { F(); }
virtual void F() = 0;
};
void A::F()
{
}
Правда легальным от этого данный код бы не стал все равно, ибо такие pure virtual функии разрешается вызвать только при помощи указания полностью квалифицировнного имени функции ('A::F()'), т.е. Comeau и GCC по-прежнему будут ругаться.