Ecco una classe con un metodo non definito. Sembra compilatori consentono istanze di questa classe per essere costruiti, a condizione che la funzione di membro non definita non viene mai chiamato:Sono consentiti tutti i metodi non definiti non utilizzati?
struct A {
void foo();
};
int main() {
A a; // <-- Works in both VC2013 and g++
a.foo(); // <-- Error in both VC2013 and g++
}
Ecco una situazione simile, ma che coinvolge l'ereditarietà. Sottoclasse Bar
estende la classe base . Foo
definisce un metodo g()
. Bar
dichiara lo stesso nome metodo, ma non la definisce:
#include <iostream>
struct Foo {
void g() { std::cout << "g\n"; }
};
struct Bar : Foo {
void g();
};
int main() {
Bar b; // Works in both VC2013 and g++
b.Foo::g(); // Works in both VC2013 and g++
b.g(); // Error in both VC2013 and g++
}
Ecco una variazione di quanto sopra. L'unica differenza è che qui è g()
virtual
sia Foo
e Bar
:
#include <iostream>
struct Foo {
virtual void g() { std::cout << "g\n"; }
};
struct Bar : Foo {
virtual void g();
};
int main() {
Bar b; // Works in g++. But not in VC2013, which gives
// 'fatal error LNK1120: 1 unresolved externals'
b.Foo::g(); // Works in g++, but VC2013 already failed on b's construction
b.g(); // Error in g++, but VC2013 already failed on b's construction
}
Vedi le osservazioni di codice per il contrasto di un comportamento differente tra il VC2013 e g ++.
- Quale compilatore è corretto, se presente?
- Perché il compilatore di VC2013 ha alcuni reclami diversi nella sua versione con la parola chiave
virtual
rispetto a quella nella sua versione senza la parola chiavevirtual
? - Sono sempre consentiti metodi non definiti non utilizzati? In caso contrario, quali sono tutti i casi in cui sono non consentiti?
- La dichiarazione
Bar
dig()
conta come prioritaria anche seBar
non fornisce una definizione?
Il vtable fa riferimento al costruttore e ha bisogno degli indirizzi delle funzioni virtuali, quindi l'errore di VC2013 sembra ragionevole. – BartoszKP