Re: dynamic cast and typeid
* matish:
Alf P. Steinbach ha scritto:
Try to post some code.
ok, I try to be as concise as I can.
//this one is linked in a.so file:
//file objects.h
#include <string>
class A {
public:
virtual std::string getClassName() const;
}
virtual ~A();
};
class B : public A {};
//file objects.cpp
std::string A::getClassName() const{
return typeid(*this).name();
}
A::~A() {}
//this one is linked in b.so file
//file container.h
#include <iostream>
#include "objects.h"
class Container {
public:
Container();
void setObject(A* o);
template<typename T>
T *getObjectAs() {
T* t = dynamic_cast<T*>(var);
if(t == NULL)
std::cout << "Object is of type " << var->getClassName() <<
" but you required " << typeid(T).name() << std::endl;
return t;
}
private:
A* var;
};
//container.cpp
void Container::setObject(A* o) {
var = o;
}
//now main.c
#include "container.h"
#include "objects.h"
int main() {
B* b = new B();
Container cont;
cont.setObject(b);
B* b1 = cont.getObjectAs<B>();
return 0;
}
Well, The correponding method in my real application prints out:
Object is of type B but you required B
hope this helps in understanding what the code I have does.
There are some issues as C++ code: need to include <typeinfo> (I think, at least
g++ says so), & need body for Container default constructor.
However, I think the problem you experience has only to do with use of
dynamically linked libraries.
The C++ standard doesn't address dynamically linked libraries, but from a
practical point of view what's happening is probably that the B-object is set up
(by code in one library) with a vtable that's different from the one
dynamic_cast is checking for (code in another library).
Apart from fixing the design (consider visitor pattern or simply introducing
relevant virtual member functions so you don't have to downcast), you may get
this to "work" by delegating the downcasting to the class in question, like
class B : public A
{
public:
static B* downcasted( A* p );
};
//file objects.cpp
B* B::downcasted( A* p ) { return dynamic_cast<B*>( p ); }
//file container.h
class Container {
public:
Container() {}; // Added body.
void setObject(A* o);
template<typename T>
T *getObjectAs() {
T* t = T::downcasted( var );
if(t == NULL)
std::cout << "Object is of type " << var->getClassName() <<
" but you required " << typeid(T).name() << std::endl;
return t;
}
private:
A* var;
};
Cheers, & hth.,
- Alf
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?