Страницы

Поиск по вопросам

пятница, 20 декабря 2019 г.

Чистые виртуальные функции и чистый виртуальный деструктор обьявленные с пустым телом

#cpp


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

class A {
 public:
     ~A() = 0 {}
     //...
}


Что так не то что нельзя, но и нужно так обьявлять...

Вопрос

Скажите пожалуйста, зачем чистой виртуальной функции тело? Тело чего? Где смысль
чистой виртуальности тогда? И в конце концов, если это правда, почему тогда мой компилятор
выдает ошибку? Это что то новое после C++14?..

Вот ошибка моего компилятора:

C:\Users\Mk\Documents\H\C++\test\main.cpp:12: error: pure-specifier on function-definition
virtual ~A() = 0 {} 

    


Ответы

Ответ 1



Формально в 10.4.2 есть замечание- Объявление функции не может содержать одновременно чистый-спецификатор и описание функции. ■ Пример. struct C { virtual void f() = 0 { }; // неправильно }; Конец примера. Но при этом ее можно определять: Описывать чистую виртуальную функцию необходимо только в случае, когда она вызывается посредством синтаксиса квалифицированного-идентификатора (5.1), или похожим образом (12.4). Т.е., похоже, что чисто виртуальная функция может быть определена, но только не в объявлении.

Ответ 2



Если функция является pure virtual, то попытка виртуального вызова такой функции приводит к неопределенному поведению. На этом факте основана популярное верование в то, что у pure virtual функции не может/не должно быть тела. Однако язык предоставляет средства для прямого (невиртуального) вызова виртуальных функций через указание квалифицированного имени метода some_object_ptr->SomeClass::some_method(); Таким способом можно вызывать виртуальные функции напрямую, без использования механизмов виртуального вызова. Таким способом можно спокойно вызывать и pure virtual функции. При этом если у вызываемой pure virtual функции нет определения (нет тела), то это будет являться таким же нарушением ODR, как и для обычных функций. (Вопрос во многом аналогичен вопросу о том, могут ли вызовы виртуальных функций быть встроенными (inlined)). Деструктор класса - функция особая. Деструктор класса-предка всегда неявно вызывается напрямую из деструкторов классов-потомков. Поэтому если у класса-предка есть хотя бы один инстанциируемый в программе класс-потомок, то деструктору класса-предка обязательно нужно определение. Является ли этот деструктор pure virtual или не является - значения не имеет. Выдаваемая вашим компилятором ошибка не имеет никакого отношения к теме наличия или отсутствия тела у pure virtual функции. Ошибка выдается из-за того, что в С++ не существует синтаксиса для определения pure virtual функции прямо в теле класса. Такие функции надо определять отдельно, за пределами класса.

Комментариев нет:

Отправить комментарий