Forward-Deklaration und typeid
-
20-09-2019 - |
Frage
Ich möchte die Art eines Super A
gegen den Typ einer Unterklasse B
überprüfen (mit einer Methode innerhalb der übergeordneten Klasse A
, so dass B
sie erben werden).
Hier ist, was ich dachte, den Trick (das heißt, die Verwendung von Vorwärts-Erklärung):
#include <iostream>
#include <typeinfo>
using namespace std;
class B;
class A {
public:
int i_;
void Check () {
if (typeid (*this) == typeid (B))
cout << "True: Same type as B." << endl;
else
cout << "False: Not the same type as B." << endl;
}
};
class B : public A {
public:
double d_;
};
int main () {
A a;
B b;
a.Check (); // should be false
b.Check (); // should be true
return 0;
}
Allerdings ist dieser Code nicht kompilieren. Der Fehler, den ich bekommen ist:
main.cc: In member function ‘void A::Check()’:
main.cc:12: error: invalid use of incomplete type ‘struct B’
main.cc:6: error: forward declaration of ‘struct B’
Wie kann ich dieses Problem lösen?
Lösung
Ich denke, dass das Problem, das Sie versuchen zu lösen ist viel besser gehandhabt durch eine virtuelle Methode:
class A
{
public:
virtual bool Check() { return false; };
}
class B : public A
{
public:
// override A::Check()
virtual bool Check() { return true; };
}
Methoden in der Basisklasse A sollen nicht wissen müssen, ob das Objekt „wirklich“ ein A oder ein B Das ist eine Verletzung der grundlegenden objektorientierte Designprinzipien. Wenn das Verhalten Bedürfnisse zu ändern, wenn das Objekt ein B ist, dann ist das Verhalten sollte von virtuellen Methodenaufrufen in B und behandelt definiert werden.
Andere Tipps
Sie einfach die Definition von Check bewegen () aus dem Körper von A:
#include <iostream>
#include <typeinfo>
using namespace std;
class B;
class A {
public:
int i_;
void Check ();
};
class B : public A {
public:
double d_;
};
void A::Check () {
if (typeid (*this) == typeid (B))
cout << "True: Same type as B." << endl;
else
cout << "False: Not the same type as B." << endl;
}
int main () {
A a;
B b;
a.Check (); // should be false
b.Check (); // should be true
return 0;
}
Eine Möglichkeit wäre die Definition von Check
aus der Klassendefinition zu ziehen, so dass B
definiert ist, wenn der Compiler auf die Funktionsdefinition wird.
class A {
//...
void Check();
//...
};
class B { /* ... */ };
void A::Check() {
//...
}
Bewegen Sie die Definition des Überprüfungs unten Ihre Erklärung der Klasse B.
Bewegen Sie einfach die Funktion Körper nach der Erklärung von B.
#include <iostream>
#include <typeinfo>
struct A
{
int i_;
void Check();
};
struct B : A
{
double d_;
};
void A::Check()
{
using namespace std;
if (typeid (*this) == typeid (B))
{
cout << "True: Same type as B." << endl;
}
else
{
cout << "False: Not the same type as B." << endl;
}
}
int main()
{
A a;
B b;
a.Check(); // should be false
b.Check(); // should be true
return 0;
}
Hallo, wenn Sie die Definition von A selbst setzen :: Prüfen außerhalb der Klasse nicht das Ergebnis, was Sie erwarten. Dies liegt daran, die B dieses convert zu einem A-Objekt in der Methode Objekt so deutet dies auf einem A-Objekt somit die typeids sind immer anders. Zur Lösung dieses declare der Methode virtuell.
Allerdings habe ich immer noch nicht verstehen, warum Sie einen solchen Test O_o ausführen wollen ?? Und wie CAdaker sagte, dies ist keine gute Praxis