Déclaration avant et typeid
-
20-09-2019 - |
Question
Je voudrais vérifier le type d'un A
superclasse contre le type d'une sous-classe de B
(avec une méthode dans la superclasse A
, de sorte que B
héritera).
Voici ce que je pensais a fait l'affaire (c'est l'utilisation de la déclaration avant):
#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;
}
Toutefois, ce code ne compile pas. L'erreur que je reçois est:
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’
Comment pourrais-je résoudre ce problème?
La solution
Je pense que le problème que vous essayez de résoudre est beaucoup mieux géré par une méthode virtuelle:
class A
{
public:
virtual bool Check() { return false; };
}
class B : public A
{
public:
// override A::Check()
virtual bool Check() { return true; };
}
Méthodes dans la classe de base A ne devrait pas besoin de savoir si l'objet est « vraiment » un A ou un B. C'est une violation des principes de conception orientée objet de base. Si le comportement doit changer lorsque l'objet est un B, alors que le comportement doit être défini dans B et gérée par des appels de méthode virtuelle.
Autres conseils
Il suffit de déplacer la définition de Check () du corps de 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;
}
Une façon serait de tirer la définition de Check
de la définition de la classe, de sorte que B
est définie lorsque le compilateur obtient à la définition de la fonction.
class A {
//...
void Check();
//...
};
class B { /* ... */ };
void A::Check() {
//...
}
Passez votre définition de la vérification ci-dessous votre déclaration de classe B.
Il suffit de déplacer le corps de la fonction après la déclaration de 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;
}
Salut, même si vous mettez la définition de A :: Vérifiez à l'extérieur de la classe le résultat ne sera pas ce que vous attendez. En effet, l'objet B cette conversion à un objet dans un la méthode donc ce fait sur un objet ainsi les A typeids sont toujours différents. Pour résoudre ce déclarer la méthode virtuelle.
Cependant, je ne comprends toujours pas pourquoi vous voulez effectuer un tel test O_o ?? Et comme CAdaker a dit que ce n'est pas une bonne pratique