2016-05-24 26 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 questo caso, è il compilatore necessario per fare ancora la ricerca v-tavolo per b->f();, o può chiamare B::f() direttamente perché è stato segnato final?Viene utilizzato per l'ottimizzazione finale in C++?

+0

risolto la domanda – tmlen

+0

'classe C: pubico A {void f() override; }; ' –

+0

' new A() 'è mal formato, perché' A' è astratto. –

risposta

21

Viene utilizzato per l'ottimizzazione in C++?

Può essere, ed è.

Come già notato, è già in uso; see here e here mostrando il codice generato per l'override con e senza final.

An optimisation along these lines si riferiscono alla "de-virtualizzazione" delle chiamate virtuali. Questo non è sempre immediatamente influenzato dal metodo final della classe. Sebbene offrano un aiuto per determinarlo, si applicano le normali regole delle funzioni virtuali e della gerarchia di classi.

Se il compilatore può stabilire che in fase di esecuzione di un metodo particolare sarà sempre chiamata (ad esempio data l'esempio OP, con un oggetto automatico), si potrebbe applicare tale an optimisation anyway, indipendentemente dal fatto che il metodo è final o meno.

Le ottimizzazioni rientrano nello as-if rule, che consentono al compilatore di applicare qualsiasi trasformazione purché il comportamento osservabile sia come se il codice originale fosse stato eseguito.

+0

Questa è stata la risposta per molto tempo, ma qualsiasi compilatore/effettivamente/utilizzante finale per la virtualizzazione? –

+1

@JohanLundberg: rapida sperimentazione con [Compiler Explorer] (https://godbolt.org/g/f02eYq) e localmente mostra che almeno gcc 6.1, clang 3.8 e MSVC++ 2015U2 usano la parola chiave 'final' per la virtualizzazione. – user786653

+1

Per chiunque sia curioso penso che questo sia il luogo in cui attualmente si verifica questa ottimizzazione in clang: [CodeGenFunction :: CanDevirtualizeMemberFunctionCall] (https://github.com/llvm-mirror/clang/blob/0e2d28ae3ba7407eb4c0b777f63e237013608261/lib/CodeGen/CGClass.cpp#L2676) – user786653