Подтвердить что ты не робот

Удаление виртуальных функций в С++ 0x

Непонятно, что произойдет, если я удалю виртуальный метод в С++ 0x:

 virtual int derive_func() = delete;

Означает ли это, что этот класс и все, что наследует от него, не могут определить/реализовать метод derive_func()? Или это ошибка/ошибка компиляции?

4b9b3361

Ответ 1

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2326.html#delete A deleted virtual function may not override a non-deleted virtual function and vice-versa. что означает его довольно бесполезное (как я прочитал, по крайней мере), единственное допустимое использование:

struct A{
     virtual void b() = delete;
};
struct B:A{
     virtual void b() = delete;
};

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

ИЗМЕНИТЬ чтобы быть полностью понятным, это ТОЛЬКО возможное отношение, дети могут не реализовывать, и вы не можете удалить не удаленный унаследованный виртуальный.

Ответ 2

flownt правильно понял, но хочу отметить, что в финальном проекте С++ 11 (N3337) соответствующий язык переместился в раздел 10.3 # 16:

Функция с удаленным определением не должна переопределять функцию который не имеет удаленного определения. Аналогично, функция, которая не имеет удаленного определения, не должно переопределять функцию с удаленное определение. 2

Мне кажется довольно понятным (раздел 8.4.3 № 1), что удаленное определение действительно считается как определение, а на самом деле встроенное определение, что означает, что удаленное определение удовлетворяет требованиям 10.3 # 11:

Виртуальная функция, объявленная в классе, должна быть определена или объявлена чистые в этом классе или оба; но никакой диагностики не требуется. 2

Однако, кажется, что текущие реализации не согласны. Вот мой тестовый пример:

struct Base {
    virtual void bar();
    virtual void foo() = delete;
};

void Base::bar() { }  // a definition of the first non-inline virtual function
int main() { Base b; }
  • Clang создает непривлекательную программу: Base::foo упоминается в таблице vtable для Base. И если вы меняете порядок foo и bar, компоновщик жалуется, что отсутствует вся таблица vtable (поскольку Clang считает, что foo - это не встроенная функция без определения). Я подал это как ошибку; мы увидим, что думают разработчики.

  • GCC жалуется на "использование" foo в конце единицы перевода, когда он создает vtable; но он правильно идентифицирует bar как первую неединичную функцию виртуального члена, независимо от порядка foo и bar.