2016-05-24 22 views
26
class A { 
public: 
    virtual void f() = 0; 
}; 

class B : public A { 
public: 
    void f() final override { }; 
}; 

int main() { 
    B* b = new B(); 
    b->f(); 
} 

In diesem Fall ist der Compiler noch erforderlich ist, um für b->f(); die V-Tabelle Lookup, oder es kann B::f() direkt anrufen, weil es final markiert wurde?Wird endgültig für die Optimierung in C++ verwendet?

+0

die Frage behoben – tmlen

+0

'Klasse C: Scham A {void f() überschreiben; }; ' –

+0

' new A() 'ist schlecht gebildet, weil' A' abstrakt ist. –

Antwort

21

Wird das letzte für die Optimierung in C++ verwendet?

Es kann sein, und ist.

Wie bereits erwähnt, wird es bereits verwendet; see here und here zeigt den generierten Code für die Überschreibung mit und ohne final.

An optimisation along these lines würde sich auf die "De-Virtualisierung" der virtuellen Aufrufe beziehen. Dies ist nicht immer sofort von der final der Klasse oder Methode betroffen. Obwohl sie Hilfe bieten, um dies zu bestimmen, gelten die normalen Regeln der virtuellen Funktionen und der Klassenhierarchie. Wenn der Compiler bestimmen kann, dass eine bestimmte Methode zur Laufzeit immer aufgerufen wird (z. B. bei einem OP-Beispiel mit einem automatischen Objekt), könnte sie an optimisation anyway anwenden, unabhängig davon, ob die Methode final ist oder nicht.

Optimierungen fallen unter die as-if rule, die es dem Compiler erlauben, jede Transformation anzuwenden, solange das beobachtbare Verhalten so ist, als wenn der ursprüngliche Code ausgeführt worden wäre.

+0

Dies war die Antwort für eine lange Zeit, aber ist irgendein Compiler/tatsächlich/Endgültig für Devirtualization? –

+1

@JohanLundberg: Schnelles Experimentieren mit dem [Compiler Explorer] (https://godbolt.org/g/f02eYq) und zeigt lokal, dass mindestens gcc 6.1, clang 3.8 und MSVC++ 2015U2 das 'final' Schlüsselwort für die Devirtualisierung verwenden. – user786653

+1

Für alle, die neugierig sind, denke ich, dass diese Optimierung derzeit in clang stattfindet: [CodeGenFunction :: CanDevirtualizeMemberFunctionCall] (https://github.com/llvm-mirror/clang/blob/0e2d28ae3ba7407eb4c0b777f63e237013608261/lib/CodeGen/CGClass.cpp#L2676) – user786653