I found that dynamic_cast
did not work in a situation where I was expecting this, and looking at typeid
objects at runtime made the situation even less clear. I just want the cast from the base to be received, and I cannot understand why it is not working.
I have a class structure like this:
class BoundaryCondition { public: virtual void DoSomething() = 0; virtual ~BoundaryCondition() { } } class ReflectingBc : BoundaryCondition { public: virtual void DoSomething(); } class MarshakBc : BoundaryCondition { public: virtual void DoSomething(); MarshakBc(double value); void changeValueLaterOn(double value); private: double value_; }
I (essentially) a std::vector<BoundaryCondition*>
, which represents the boundary conditions in the parts of the problem. I want to have this vector
and for all MarshakBc
objects inside it call changeValueLaterOn
. So I have a loop that looks like
for (std::vector<BoundaryCondition*>::iterator bc = bcPtrs_.begin(); bc != bcPtrs_.end(); ++bc) { if (std::string(typeid(MarshakBc).name()) == std::string(typeid(**bc).name()) ) { std::cerr << "SAME! "; } if (typeid(MarshakBc) != typeid(**bc)) { std::cerr << "NOT SAME "; } MarshakBc* thisBc = dynamic_cast<MarshakBc*>( &( **bc ) ); if (thisBc == NULL) { std::cerr << "...nothing\n"; continue; } thisBc->changeValueLaterOn( 1.23); std::cerr << "...set!\n"; }
If my vector has ReflectingBc*
, then a MarshakBc*
, my output looks like this:
NOT SAME ...nothing SAME! NOT SAME ...nothing
Am I misunderstanding something about dynamic_cast
and typeid
?
[The actual situation is more complicated than this because the BoundaryCondition
definition is in a different translation unit than the code above and the templates are used, etc., but the code above is very representative of what I do and the result I get .]
More details
Here is my actual procedure, which is used inside a functor, and LoAnisoBc
is a derived class, and BoundaryConditionT
is a base class:
template<class SnTraits_T, class LoTraits_T> void FillLoAnisoBcs<SnTraits_T, LoTraits_T>::operator() ( const BoundaryFaceT& bf, BoundaryConditionT& bc) { std::cerr << "Want " << typeid(LoAnisoBc).name() << "\n"; std::cerr << "Chkg " << typeid(bc).name() << "\n"; if (std::string(typeid(LoAnisoBc).name()) == std::string(typeid(bc).name()) ) { std::cerr << " SAME!"; } if (!(typeid(LoAnisoBc) == typeid(bc))) { std::cerr << "...nothing\n"; }
And here is the conclusion
Want N6detLib17cellDiffusionOned28AnisotropicBoundaryConditionE Chkg N6detLib17cellDiffusionOned27ReflectingBoundaryConditionE NOT SAME...nothing Want N6detLib17cellDiffusionOned28AnisotropicBoundaryConditionE Chkg N6detLib17cellDiffusionOned28AnisotropicBoundaryConditionE SAME! NOT SAME...nothing
So, the bcPtrs_
structure and the boundary conditions are in one dynamic library (so this is one module in Python), and the FillLoAnisoBcs
instance is in another dynamic library. Eric considers this a probable problem, and I agree.