Reputation: 3155
I would like to check the type of a superclass A
against the type of a subclass B
(with a method inside the superclass A
, so that B
will inherit it).
Here's what I thought did the trick (that is, the use of forward declaration):
#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;
}
However this code does not compile. The error I get is:
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’
How could I solve this problem?
Upvotes: 2
Views: 1359
Reputation: 1
Hi, even if you put the definition of A::Check outside the class the result won't be what you expect. This is because the B object this convert to an A object in the method so this points on a A object thus the typeids are always different. To solve this declare the method virtual.
However, I still don't understand why you want to perform such a test O_o ?? And as CAdaker said this is not good practice
Upvotes: 0
Reputation: 41378
I think that the problem you are trying to solve is much better handled by a virtual method:
class A
{
public:
virtual bool Check() { return false; };
}
class B : public A
{
public:
// override A::Check()
virtual bool Check() { return true; };
}
Methods in the base class A should not need to know whether the object is "really" an A or a B. That's a violation of basic object-oriented design principles. If the behavior needs to change when the object is a B, then that behavior should be defined in B and handled by virtual method calls.
Upvotes: 3
Reputation: 18360
Just move the function body after the declaration of 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;
}
Upvotes: 0
Reputation: 16549
Move your definition of the Check below your declaration of class B.
Upvotes: 0
Reputation: 9408
Just move the definition of Check() out of the body of 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;
}
Upvotes: 1
Reputation: 14711
One way would be to pull the definition of Check
out of the class definition, so that B
is defined when the compiler gets to the function definition.
class A {
//...
void Check();
//...
};
class B { /* ... */ };
void A::Check() {
//...
}
Upvotes: 0