2017-07-20 4 views
0

Ich möchte B::func2(int x, int y) in A::func1(x) aufrufen, wie man sie deklariert?C++ erben, wie die Methode der Unterklasse in baseclass-Methode aufrufen?

class A { 
public: 
    void func1(int x); 
    virtual void func2(int x, int y); // do not need implement in A 
}; 

class B : public A { 
public: 
    void func2(int x, int y) override; // override 
}; 

void A::func1(int x) { 
    int y; 
    func2(x, y); // I want to use the version of A's subclass 
} 

int main() 
{ 
    B b; 
    b.func1(x); // call A::func1(x) first then call B::func2(x, y) 
} 

Es wird nicht, stattdessen wird folgende Fehlermeldung kompilieren wird

> clang++ test.cpp -std=c++11

Undefined symbols for architecture x86_64:

"typeinfo for A", referenced from:

typeinfo for B in test-bbac7f.o 

"vtable for A", referenced from:

A::() in test-bbac7f.o 

NOTE: a missing vtable usually means the first non-inline virtual member > function has no definition.

ld: symbol(s) not found for architecture x86_64

clang: error: linker command failed with exit code 1 (use -v to see invocation)

+4

Das passiert nicht schon mit dem Code, den Sie anzeigen? Wie hast du es getestet? Welche Ergebnisse erhalten Sie und welche Ergebnisse haben Sie erwartet? –

+2

Warum möchten Sie 'B :: func2()' in 'A :: func1()' aufrufen? Was benötigen Sie, wenn das eigentliche Objekt kein 'B' ist? – Peter

Antwort

1

Paar Dinge:

1.) Stellen Sie A::func2 rein virtuell her, indem Sie =0; anhängen, ODER definieren Sie seinen Körper mit geschweiften Klammern {} (beachten Sie, dass es leer gelassen werden kann).

2.) Definieren Sie den Körper von B::func2 mit Klammern {} (wieder, kann leer gelassen werden).

Sie können keine Funktion aufrufen, die nicht an erster Stelle definiert ist.

2

// call A::func1(x) first then call B::func2(x, y)

gezeigt Es ist genau das, was in Ihrem Fall passieren wird. Siehe at Coliru.

Im Grunde geht es um virtuelle Anrufe. Da func2 als "virtual" markiert ist, wird der Aufruf, wenn er aufgerufen wird A::func1, durch vtable gehen, daher wird eine überschriebene Methode B::func2 aufgerufen.

Es ist umgekehrt: Wenn Sie A::func1 wollen A::func2 aufzurufen, müssten Sie es explizit schreiben:

void A::func1(int x) { 
    int y; 
    A::func2(x, y); // explicitly tell to use A's version; otherwise the overriden method from the subclass is invoked. 
} 

P. S.This answer rät, A::func2 rein virtuell zu machen. Dies könnte sinnvoll sein, wenn Sie nicht die Implementierung von A::func2 verwenden möchten. Wenn aus welchem ​​Grund auch immer, müssen Sie innerhalb A::func2 auch einige funktionelle Code haben, dann typisches Muster ist ein Aufruf an A::func2 in einer abgeleiteten Klasse hinzuzufügen, wie diese

void B::func2(int x, int y) { 
    A::func2(x, y); 
    // do something specific for B 
} 
Verwandte Themen