Frage Löschen von virtuellen Funktionen in C ++ 0x


Es ist nicht klar, was passiert, wenn ich eine virtuelle Methode in C ++ 0x lösche:

 virtual int derive_func() = delete;

Bedeutet dies, dass diese Klasse und alles, was von ihr erbt, nicht definieren / implementieren kann derive_func() Methode? Oder ist das illegal / kompilieren Fehler?


20
2017-10-11 21:25


Ursprung


Antworten:


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. was bedeutet, dass es ziemlich nutzlos ist (wie ich es zumindest gelesen habe), wäre der einzig gültige Gebrauch:

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

Das ist völlig nutzlos, da die Funktion nie aufgerufen werden kann. bei nicht virtuellen Funktionen ist die Verwendung eher gerechtfertigt

BEARBEITEN um vollständig klar zu sein, ist dies die NUR mögliche Beziehung, Kinder können nicht implementieren und Sie können nicht nicht gelöschte geerbte virtuelle löschen.


15
2017-10-11 22:33



flownt hat es richtig gemacht, aber ich möchte darauf hinweisen, dass im letzten C ++ 11-Entwurf (N3337) die entsprechende Sprache in Abschnitt 10.3 # 16 verschoben wurde:

Eine Funktion mit einer gelöschten Definition darf eine Funktion nicht außer Kraft setzen   Das hat keine gelöschte Definition. Ebenso eine Funktion, die   hat keine gelöschte Definition darf eine Funktion nicht mit überschreiben   eine gelöschte Definition2

Es scheint ziemlich klar zu sein mir (Abschnitt 8.4.3 # 1) dass a gelöschte Definition zählt tatsächlich als Definitionund in der Tat eine Inline-Definition, was bedeutet, dass eine gelöschte Definition 10.3 # 11 erfüllt:

Eine in einer Klasse deklarierte virtuelle Funktion muss definiert oder deklariert werden   rein in dieser Klasse oder beides; aber keine Diagnose ist erforderlich.2

Es scheint jedoch, dass aktuelle Implementierungen nicht übereinstimmen. Hier ist mein Testfall:

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 produziert ein nicht verknüpfbares Programm: Base::foo ist in der Vtable für erwähnt Base. Und wenn Sie die Reihenfolge tauschen foo und barklagt der Linker, dass die gesamte vtable fehlt (weil Clang denkt) foo ist eine Nicht-Inline-Funktion ohne Definition). Ich habe dies als Fehler abgelegt; Wir werden sehen, was die Entwickler denken.

  • GCC beschwert sich über einen "Gebrauch" von foo am Ende der Übersetzungseinheit, wenn die Vtable erstellt wird; aber es identifiziert sich richtig bar als erste nicht-inline virtuelle Elementfunktion, egal in welcher Reihenfolge foo und bar.


5
2017-08-24 00:59