Click to See Complete Forum and Search --> : checking instance of an object


bwilson
May 29th, 2002, 06:12 PM
Hi,

Im originally a java programmer and am only new to C++.

I have create a simple base class and two sub-classes.

class Base
{
public:
Base();
};

class Child1 : public Base
{
public:
Child1();
};

class Child2 : public Base
{
public:
Child2();
};

In a main program I instantiate an object as follows
Base* base_p = new Child1();

Is there a way of checking whether that variable is an instance of Base or an instance of Child1

In java you can use instanceof, is there a similar keyword in C++?

Thanks...

jfaust
May 29th, 2002, 08:03 PM
Well, I can think of two ways to do it, neither of which is good. Ideally, a user of the class should not care. Anything that behaves different in one class should be handled via a virtual method.

Now, on to your question. You could try casting it to the base class type as follows:
Child1* child = dynamic_cast<Child1*>(myObject);
if( child )
// it is the child class, not the base

Another way to do it would be to build that information into the class, such as a virtual method isChild1 that returns false in the base class, and true in Child1. Similarly, you could create a method that returns an enumerated type corresponding to the type of the class. This value would be set by each of the constructors.

Again, try to avoid doing this. In a perfect world, you would never need to do this type of thing.

Jeff

bwilson
May 29th, 2002, 08:39 PM
Thanks for your comments jeff, ill explain the real actual situation and see if you can help me out. This is for something at work

Currently we have two classes NavMsg and NavMsg_2_1

We have a thrid class called NavTest which behaves in a particular way depending upon a command line parameter.

If the parameter is 2_1 then the class will instantiate a NavMsg_2_1 object and execute various member function in NavTest with a parameter for that particular object type. There is duplicate code in the NavTest class because of the fact that the functions are duplicated to handle different parameter types.

What we want is to have a base class that the NavMsg and NavMsg_2_1 inherit from and in the NavTest class instantiate a base class type and pass that object to the member functions in NavTest. This is all in attempt to elimiate the duplicate function and code.

- Brett

Jupiter
May 29th, 2002, 10:39 PM
Hi brett,
There is one mechanism in c++ by which u can identify the type at run time. Its same as ur InstanceOf which u use in java. Its called RTTI Run time type Identification. Using this u can get the class name at run time and solve ur problem. For this u have to enable RTTI in the setting option and do some coding. If you want then i can send u the example..

- Hemant

jfaust
May 29th, 2002, 10:49 PM
So let's say the setup looks like this:

class NavMsgBase
{
virtual void doit(NavTest* nav) = 0;
};

class NavMsg : public NavMsgBase
{
virtual void doit(NavTest* nav);
};

class NavMsg_2_1 : public NavMsgBase
{
virtual void doit(NavTest* nav);
};

class NavTest
{
public:
void processMessage(NavMsgBase* msg);
NavMsgBase* createNewMessage(const CString& parameter);
void doit1();
void doit2();
void doit3();
};

Of course this will be oversimplified, and maybe downright wrong if I misunderstood you, but hopefully it will give you an idea.

As I understand it NavTest is responsible for creating the correct NavMsgBase class depending on the input parameter. I defined the method createNewMessage() to handle this.

Now, depending on the type created, you need to call various methods in NavTest. I created these various things and called them doit1, doit2, and doit3.

After you create the object in createNewMessage(), you could call doit() on that new message object. Since this is virtual, it's behavior is defined by the derived class that it was instantiated as. For instance, the NavMsg class could call doit1 and doit2 and the class NavTest_2_1 could call doit1 and doit3.

Any code in NavTest that behaves different based on the type of NavMsgBase class should be moved to one of those classes. Let any unique behavior be handled by that class.

One more thing--you said that NavTest will "instantiate a base class type." You should probably never do this. Only instantiate one of the derived class types.

Good luck,

Jeff

bwilson
May 30th, 2002, 12:05 AM
Hemant,

could you please send me the example...

Thanks,
Brett

jfaust
May 30th, 2002, 01:33 AM
It's usually a sign of a bad architecture to use RTTI, casting, or other techniques to determine what type of object you are dealing with.

If you use it, you trade one problem(duplicate code) for another(lack of architecture). These are both maintenance issues and I'd be hard pressed to determine which is worse. The architecture issue is not as obvious, but it will come back to bite you. It always does.

Jeff

Jupiter
May 30th, 2002, 05:11 AM
hi brett,
For RTTI You have to follow just three steps. Its very simple.
1] Include TypeIno.h
2] Enable RTTI in ur project - >settings...Category-> C++ Language.. Check the checkbox for enabling RTTI
3] Use any of the function like TypeID etc. depending on ur need.

Following simple code example will give you a clear picture of how you use it in ur code.

#include <iostream.h>
#include <typeinfo.h>

class base
{
public:
base()
{
cout<<"base constructor called...\n";
}
~base()
{
cout<<"base destructor called...\n";
}
virtual void add() = 0;
};

class child1:public base
{
public:
child1()
{
cout<<"child1 constructor called...\n";
}
~child1()
{
cout<<"child1 destructor called...\n";
}
virtual void add()
{
cout<<"\n"<<"Inside add of child1....";
}
};

class child2:public base
{
public:
child2()
{
cout<<"child2 constructor called...\n";
}
~child2()
{
cout<<"child2 destructor called...\n";
}
virtual void add()
{
cout<<"\n"<<"Inside add of child2....";
}
};

void main()
{
base *pBase;
pBase = new child1;
cout<<"\n"<<"Class Name :- "<<typeid(*pBase).name()<<"\n";
pBase->add();
delete pBase;

}

When u run the above code u ll get the name of the class in pBase i.e Child1..

Hope this will help u...........

Hemant

bwilson
June 3rd, 2002, 05:40 PM
Thanks for all your help guys...

- Brett