feelfree
feelfree

Reputation: 11753

How to know the type of object a pointer points to in C++?

Suppose I have defined two classes based on one basic class:

class Basic
{
public:
   int i;
};
class DerivedA:public Basic
{
 public:
   int j;
};
class DerivedB:public Basic
{
 public:
   int k;
};

Then now have a class named Collect, which contains the pointer to the Basic class

class Collect
{
 public:
    Basic *pBasic;
    void run();

};

In this class, a function run() has been defined, which will perform some operations based on the type of the object the pointer points to:

void Collect::run()
{
  if (pBasic points to DerivedA object)
  {

   }

  if (pBasic points to DerivedB object)
  {

   }

};

Then my question is as follows:

Upvotes: 2

Views: 267

Answers (3)

lrineau
lrineau

Reputation: 6274

Unless your base class have virtual functions, the pointee of your pointer will always be of type Basic, and have the behavior of an object of type Basic. Actually, even with virtual function, a pointer of type Basic* always points to an object of type Basic. But the ''dynamic type'' of the pointee can be different.

If your base class have at least one virtual function, then your can rely on the Run-time type information: you can use dynamic_cast or typeid to get the dynamic type of the pointee.

Upvotes: 0

danielschemmel
danielschemmel

Reputation: 11116

To perform a check like this your base class Basic needs to have at least one virtual member. Since you wish to build a class hierarchy, I would tend to make ~Basic virtual to ensure it will be properly deleted at the same time.

The reasoning behind this is that the by including a virtual member, you force each object of the class to contain a pointer to the class specific vtable, which the implementation can then use to perform your check.

class Basic
{
public:
    int i;
    virtual ~Basic() { }
};
class DerivedA:public Basic
{
public:
    int j;
};
class DerivedB:public Basic
{
public:
    int k;
};

Now you can write your check:

void Collect::run()
{
    if (DerivedA* pDerived = dynamic_cast<DerivedA*>(pBasic)) { }
    if (DerivedB* pDerived = dynamic_cast<DerivedB*>(pBasic)) { }
};

The dynamic_cast will return a nullptr if it fails, so you will only enter the body of the if when your cast succeeded and pDerived contains a valid pointer to the right derived object.

Upvotes: 3

Luca Davanzo
Luca Davanzo

Reputation: 21510

In c++ we usually use Base class, not Basic class.

Anyway, in general, if your base class is polymorphic (that contains virtual functions) you can use dynamic_cast:

class Base {
public:
    Base();
    virtual ~Base();
    void test() { cout << "Base" ; }
};

class Derived: public Base {
public:
   void test() { cout << "Derived" ; }
}; 

void main() {
   Base* a = new Derived();
   if(dynamic_cast<Derived*>(a)) {
      a->test(); /* print "Derived" */
   }
}

This means that object "a" has "static-type": Base; and "dynamic-type": Derived.

Upvotes: 0

Related Questions