Удаление виртуальных функций в C ++ 0x - PullRequest
20 голосов
/ 12 октября 2010

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

 virtual int derive_func() = delete;

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

Ответы [ 2 ]

15 голосов
/ 12 октября 2010

http://www.open -std.org / jtc1 / sc22 / wg21 / docs /apers / 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;
};

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

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

5 голосов
/ 24 августа 2012

flownt понял все правильно , но я хочу отметить, что в окончательном варианте C ++ 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...