Pure-specifier по определению функции
При компиляции на GCC я получаю ошибку: pure-specifier в определении функции, но не тогда, когда компилирую тот же код с помощью VS2005.
class Dummy {
//error: pure-specifier on function-definition, VS2005 compiles
virtual void Process() = 0 {};
};
Но когда определение этой чистой виртуальной функции не является встроенным, оно работает:
class Dummy
{
virtual void Process() = 0;
};
void Dummy::Process()
{} //compiles on both GCC and VS2005
Что означает ошибка? Почему я не могу сделать это inline? Является ли законным избегать проблемы с компиляцией, как показано во втором примере кода?
Ответы
Ответ 1
Хорошо, я только что кое-что узнал. Чистая виртуальная функция должна быть объявлена следующим образом:
class Abstract
{
public:
virtual void pure_virtual() = 0;
};
У него может быть тело, хотя незаконно включать его в точку объявления. Это означает, что для того, чтобы иметь тело, чистая виртуальная функция должна быть определена вне класса. Обратите внимание, что даже если у него есть тело, функция все равно должна быть переопределена любыми конкретными классами, полученными из Abstract
. У них просто есть возможность вызывать Abstract::pure_virtual()
явно, если им нужно.
Подробности здесь.
Ответ 2
Стандарт С++, 10.4/2:
объявление функции не может предоставить как чисто-спецификатор, так и определение
Ответ 3
Этот синтаксис:
virtual void Process() = 0 {};
не является законным С++, но поддерживается VС++. Именно поэтому Стандарт не разрешает мне это делать. Ваш второй пример является законным.
Ответ 4
Чистые виртуальные функции в С++ по определению не имеют определения в объявлении.
Второй блок кода не позволяет избежать проблемы с компилятором. Он реализует чистую виртуальную функцию так, как она была предназначена.
Вопрос в том, почему вам нужно объявить его чистым виртуальным, если вы намерены реализовать по умолчанию?
Ответ 5
Это категорически запрещено: декларатор, который может включать в себя чистые спецификаторы, т.е. член-декларатор, появляется только в объявлениях, которые не являются определениями. [Class.mem]
член-декларация:
атрибут-спецификатор-сл <суб > неавтоматическогосуб > decl-specifier-seq opt member-declarator-list opt;
функция четкости
[...]
member-declarator-list: Member-declarator
член-описатель-лист, член-декларатор
member-declarator: declarator virt-specifier-seq opt чистый-спецификатор opt
declarator brace-or-equal-initializer opt
идентификатор opt attribute-specifier-seq opt:
константное выражение
Грамматика определения функции не включает в себя спецификатор pure, [dcl.fct.def.general]:
функция четкости:
атрибут спецификатор-сл <суб > неавтоматическогосуб > decl-specifier-seq opt declarator virt-specifier-seq opt function-body
Ответ 6
Конечно, вы можете обеспечить тело чистой виртуальной функцией. Эта функция будет указана на этот абстрактный класс vtable. В противном случае один и тот же слот будет указывать на функцию ловушки, специфичную для компилятора, такую как __cxa_pure_virtual
для GCC. Конечно, в этом нет ничего об этом в стандарте.