2

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:

  • With C++, is it possible to know the type of object the pointer points to?
  • Is it a good practice to perform something different based on the type of object the pointer points to as illustrated in run function?
7
  • 6
    Yes, at least it is possible to check whether it points to an object of a specific type. No. Typically you use polymorphism for that. Commented Apr 28, 2014 at 15:14
  • 2
    We usually say "Base", not "Basic". Commented Apr 28, 2014 at 15:16
  • 1
    @juanchopanza: That's already polymorphism. You mean virtual dispatch. Commented Apr 28, 2014 at 15:16
  • Use typeid if you want, but the compiler does it for you anyway. Commented Apr 28, 2014 at 15:20
  • check out dynamic_cast, and I agree with @juansanchopanza. Casts are a hacky way of programming, use normal C++ polymorphism. Commented Apr 28, 2014 at 15:22

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.