views:

59

answers:

3

Hi, i have

class Base
{
   Base* next;
}

class Class1 : Base
{
}

Base* pBase = new Base();
Class1* pTest = new Class1();
pBase->next = pTest;

Class1* pClass1;
pClass1 = (Class1*)pBase->next;

I want to be able to write

pClass1 = pBase->next;

and get no compilation error C2440 (cannot convert). Or in other words I want pClass1 point to a class that pBase->next points to.

Is it possible with some operator overloading? How to do it?

+1  A: 

If - at development time - you're sure that next points to an instance of Class1, make next a Class1 pointer instead of a Base pointer.

If you're not sure, and you only know it at compile time, you have to use a dynamic cast (possibly next will point to a Class2 instance later).

Patrick
It's the second case with Class2 or more that derive from Base class. How do I use dynamic cast in such case?
AOI Karasu
pClass1 = dynamic_cast<Class1 *>(pBase->next);if (!pClass1) std::cout << "back luck, it's not a Class1 instance" << std::endl;
Patrick
Not, what I wanted. pClass1 = dynamic_cast<Class1 *>(pBase->next); is even longer than pClass1 = (Class1*)pBase->next; and I wanted simple pClass1 = pTest1->next;
AOI Karasu
Yep, but a dynamic cast is safe, in case you end up with a Class2 that also inherits from Base.The C-type cast that you use here is in fact a static cast in C++. If you are 100% sure that Base->Next points to a Class1 instance, it's faster. But if you cannot be sure about that, using a static cast is asking for trouble.
Patrick
Oh, ok. So you say that (Class1*) is in fact static_cast<Class1*>? Sorry for my ignorance.
AOI Karasu
+1  A: 

The closest I can get to what you are after is this:

class Class1;

class Base
{
public:
    Base* next;

    operator Class1*()
    {
        return (Class1*)this;
    }
};

class Class1 : public Base
{
};

and:

Base* pBase = new Base();
Class1* pTest = new Class1();
pBase->next     = pTest;

Class1* pClass1;
pClass1 = *pBase->next;

But this is really messing around with C++ in ways that you will pay for severely later. Just use one of the casts mentioned by Patrick.

Goz
Good, but I don't want the Base class directly refer to Class1 since it can be Class2, Class3 that inherits Base.
AOI Karasu
+2  A: 
template<class T>
class Base 
{ 
   T* next; 
} 

class Class1 : Base<Class1> 
{ 
} 

Class1* pTest1 = new Class1(); 
Class1* pTest2 = new Class1(); 
pTest1->next = pTest2;

Class1* pClass1; 
pClass1 = pTest1->next; 
Alexey Malistov
This model is exactly what I wanted. Thank you.
AOI Karasu
BTW - if someone would want to refer to the class itself from with the template class, one should use T* self = static_cast<T*>(this);
AOI Karasu
The CRTP shows itself, again! (see http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)
Marcus Lindblom