Note that there are some explanatory texts on larger screens.

plurals
  1. POdynamic_cast issues: typeid object is not equal, but name is equal
    text
    copied!<p>I found that <code>dynamic_cast</code> didn't work in a situation where I expected it to, and looking at the <code>typeid</code> of the objects at runtime has made the situation even less clear. I just want a cast from base to derived, and I can't figure out why it's not working.</p> <p>I have a class structure something like this:</p> <pre><code>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_; } </code></pre> <p>I have (essentially) a <code>std::vector&lt;BoundaryCondition*&gt;</code> that represents boundary conditions in parts of the problem. I want to be able to take that <code>vector</code> and, for all <code>MarshakBc</code> objects inside it, call <code>changeValueLaterOn</code>. So I have a loop that looks like</p> <pre><code>for (std::vector&lt;BoundaryCondition*&gt;::iterator bc = bcPtrs_.begin(); bc != bcPtrs_.end(); ++bc) { if (std::string(typeid(MarshakBc).name()) == std::string(typeid(**bc).name()) ) { std::cerr &lt;&lt; "SAME! "; } if (typeid(MarshakBc) != typeid(**bc)) { std::cerr &lt;&lt; "NOT SAME "; } MarshakBc* thisBc = dynamic_cast&lt;MarshakBc*&gt;( &amp;( **bc ) ); if (thisBc == NULL) { std::cerr &lt;&lt; "...nothing\n"; continue; } thisBc-&gt;changeValueLaterOn( 1.23); std::cerr &lt;&lt; "...set!\n"; } </code></pre> <p>If my vector contains a <code>ReflectingBc*</code>, then a <code>MarshakBc*</code>, my output looks like:</p> <pre><code>NOT SAME ...nothing SAME! NOT SAME ...nothing </code></pre> <p>Am I misunderstanding something about <code>dynamic_cast</code> and <code>typeid</code>?</p> <p>[The actual situation is more complicated than this because the definition of <code>BoundaryCondition</code> is in a different translation unit than the above code, and templates and such are involved, but the above code is very representative of what I'm doing and the result I'm getting.]</p> <hr> <h2>More details</h2> <p>Here is my actual routine, which is used inside a functor, and <code>LoAnisoBc</code> is the derived class and <code>BoundaryConditionT</code> is the base class:</p> <pre><code>template&lt;class SnTraits_T, class LoTraits_T&gt; void FillLoAnisoBcs&lt;SnTraits_T, LoTraits_T&gt;::operator() ( const BoundaryFaceT&amp; bf, BoundaryConditionT&amp; bc) { std::cerr &lt;&lt; "Want " &lt;&lt; typeid(LoAnisoBc).name() &lt;&lt; "\n"; std::cerr &lt;&lt; "Chkg " &lt;&lt; typeid(bc).name() &lt;&lt; "\n"; if (std::string(typeid(LoAnisoBc).name()) == std::string(typeid(bc).name()) ) { std::cerr &lt;&lt; " SAME!"; } if (!(typeid(LoAnisoBc) == typeid(bc))) { std::cerr &lt;&lt; "...nothing\n"; } // if we're not an "anisotropic BC", don't do anything LoAnisoBc* anisoBc = dynamic_cast&lt;LoAnisoBc*&gt;( &amp;bc ); if (anisoBc == NULL) { std::cerr &lt;&lt; "...nothing\n"; return; } anisoBc-&gt;setFCoeff( fCoeff_ ); std::cerr &lt;&lt; "; set fCoeff = " &lt;&lt; fCoeff_ &lt;&lt; "\n"; } </code></pre> <p>And here's the output</p> <pre><code>Want N6detLib17cellDiffusionOned28AnisotropicBoundaryConditionE Chkg N6detLib17cellDiffusionOned27ReflectingBoundaryConditionE NOT SAME...nothing Want N6detLib17cellDiffusionOned28AnisotropicBoundaryConditionE Chkg N6detLib17cellDiffusionOned28AnisotropicBoundaryConditionE SAME! NOT SAME...nothing </code></pre> <hr> <p>So the <code>bcPtrs_</code> structure and the boundary conditions are in one dynamic library (so it's one module in Python), and the instantiation of <code>FillLoAnisoBcs</code> is in another dynamic library. Erik suggests this as the probable issue and I agree.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload