[Dev-C++] Open question: (static|dynamic)_casting and templates in C++
Open Source C & C++ IDE for Windows
Brought to you by:
claplace
|
From: GOUAICH A. <go...@li...> - 2004-12-06 11:13:37
|
Hi there,
I was trying to port the code of a library to use it in my own project and I
found something interesting.
The problem is that if you have a class B, that extends another class A.
Then when using the template MyTemplateClass<B> does not have any
relationship with the class MyTemplateClass<A>.
You can see some experiments in the code presented below.
If someone has a more detailed documentation (specification) explaning why
this cannot be done I would appreciate.
Kind regards,
8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----
-
#include <iostream>
#include <stdlib.h>
using namespace std;
template <class T>
class Ref{
T* ptr;
public:
Ref(T* p)
{
this->ptr = p;
};
Ref( const Ref<T>& clone)
{
this->ptr = clone.ptr;
};
T* get()
{
return ptr;
}
// [added after] to make this type
// plymorphic
virtual void trick(void )
{
};
};
class A
{
public:
A()
{
};
virtual void ping()
{
cout << "A" <<endl;
};
};
class B: public A
{
public:
B():A()
{
};
virtual void ping()
{
cout << "B" <<endl;
};
};
void test_call(Ref<A>& x )
{
x.get()->ping();
//just a test
};
int main(int argc, char *argv[])
{
A* a= new A();
B* b= new B();
Ref<A>* ref_a = new Ref<A>(a);
Ref<B>* ref_b = new Ref<B>(b);
//-------------------
//test_call(*ref_a);
//->this is ok !
// output:
// $ A
// $ press any key to continue...
//-------------------
//test_call(*ref_b);
// compilation problem.
//->log:
// could not convert *reb_b to
// Ref<A>& .... mmmmm
//so try to cast....
//static_cast
//test_call(static_cast< Ref<A> >(*ref_b));
// mmmm does not work ! :(
//log:
//main.cpp:53: no matching function for call to `Ref<A>::Ref(Ref<B>&)'
//main.cpp:15: candidates are: Ref<T>::Ref(const Ref<T>&) [with T = A]
//main.cpp:11: Ref<T>::Ref(T*) [with T = A]
//ok dynamic cast now !!
//Ref<A>* tmp = dynamic_cast< Ref<A>* >(ref_b);
//if(tmp)
//{
// test_call(* tmp );
//}
//else
//{
//cout << "error with the cast...." <<endl;
//}
//main.cpp: In function `int main(int, char**)':
//main.cpp:86: cannot dynamic_cast `ref_b' (of type `class Ref<B>*') to
type `
//class Ref<A>*' (source type is not polymorphic)
//I suspect that the compiler consider Ref<A> as not
//being plymorphic ... so add a virtual method
//to this class and see what will happen...
//see [added after] in class Ref
Ref<A>* tmp = dynamic_cast< Ref<A>* >(ref_b);
if(tmp)
{
test_call(* tmp );
}
else
{
cout << "error with the cast...." <<endl;
}
// Now the program compiles but the
// during the runtime the dynamic_cast
// does not work ! ,(
//conclusion...
// even if B extends A; Ref<B> has no relationship with Ref<A>
//!!!!!!!!!! a bit strange...
//the correct method is to do as follows:
//rebuild the class manually.
A* tmp_ptr = static_cast<A* >(ref_b->get()); //or dynamic_cast
Ref<A> tmp_ref_a (tmp_ptr);
test_call(tmp_ref_a);
//And now the output is :
// $ B
// $ press any key to continue...
// ok!
system("PAUSE");
return 0;
}
|