Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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;
}

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() {
    //...
}

Move your definition of the Check below your declaration of class B.

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;
}

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top