Reputation: 1514
Is it possible what I'm trying to achieve. This is the problem:
class Content{};
class Content1 : public Content{};
class Content1_1 : public Content1{};
class Content1_2 : public Content1{};
class Content2 : public Content{};
class Content2_1 : public Content2{};
class Content2_2 : public Content2{};
class Container{
public:
Content* c;
};
Is it possible to determine if the pointer of the Container
class points to an object of Content1
or an object of a class derived from Content1
?
Thanks.
EDIT:
If I look up the type of the pointer in the container
class, it is treated as a content
type, though it might actually be a content1
or content2
type, so dynamic_cast doesn't work.
class content{};
class content1 : public content{};
class content2 : public content{};
class container{
public:
content* c;
};
int main(void)
{
container* x = new container;
x->c = new content2;
if( dynamic_cast<content1*>((content1*)x->c) == NULL){
//This doesn't fail, eventhough 'content1' and 'content2' shouldn't be compatible.
//This means that every class, derived from 'content' will be treated as 'content1' when using dynamic_cast.
}
return 0;
}
Upvotes: 2
Views: 115
Reputation: 3912
If you want to see if Content*
points to an object of a class derived from Content2
class just cast it with dynamic_cast
and see.
This works:
#include <iostream>
#include <typeinfo>
using namespace std;
class Content{public: virtual ~Content(){}};
class Content1 : public Content{public: virtual ~Content1(){}};
class Content1_1 : public Content1{public: virtual ~Content1_1(){}};
class Content1_2 : public Content1{public: virtual ~Content1_2(){}};
class Content2 : public Content{public: virtual ~Content2(){}};
class Content2_1 : public Content2{public: virtual ~Content2_1(){}};
class Content2_2 : public Content2{public: virtual ~Content2_2(){}};
class Container{
public:
Content* c;
};
int main()
{
Content* cnt=new Content2_1;
if(dynamic_cast<Content2_1*>(cnt))
cout << "True" << endl;
return 0;
}
Upvotes: 0
Reputation: 3249
If you have to know the exact runtime type of a polymorphic class, you should rethink your design. Usually it is better to either keep objects of different types in different containers (additionally or, instead of one central container) or add a virtual function to each of the derived classes which performs the action where you would have to discriminate between the types.
There is an entry in the C++ FAQ which might help you: I have a heterogeneous list of objects, and my code needs to do class-specific things to the objects. Seems like this ought to use dynamic binding but can't figure it out. What should I do?
Upvotes: 1
Reputation: 126442
If your types are polymorphic (i.e. if they have at least one virtual
function), you can use dynamic_cast<>
. The result of dynamic_cast<>
will be a null pointer (i.e. nullptr
for C++11, NULL
for C++03) in case the pointed object is not actually an instance of the specified class, or of a derived class thereof:
Container cont;
Content1* pContent1 = dynamic_cast<Content1*>(cont.c);
if (pContent1 != nullptr)
{
// cont.c points to an instance of Content1
// or a class derived from Content1
}
A common practice is to make the destructor of your base class virtual, so that objects of a class derived from your base class can be delete
d through a base class pointer (if the destructor is not virtual
, attempting to do so results in undefined behavior):
class Content //Abstract.
{
public:
virtual ~Content() { }
// ^^^^^^^
};
Upvotes: 2
Reputation: 14039
Yes, use dynamic_cast
- http://www.cplusplus.com/doc/tutorial/typecasting/
It will give you RTTI - Runtime Type Information.
Content1 * p = dynamic_cast<Content1 *>(c);
if p is non-NULL, then c points to an object which is Content1 or derived from Content1.
However, your class heirarchy needs to be polymorphic. Since your class Content
is Abstract (I am assuming you have a pure virtual function in Content), your whole heirarchy automatically is polymorphic.
Upvotes: 1