I'd an issue about C++ destructor behavior, higher productivity appealing than other things. I've the next classes:

Base.h

class BaseB;

class BaseA
{
    public:
        virtual int MethodA(BaseB *param1) = 0;
};

class BaseB
{
};

Imp.h

#include "Base.h"
#include <string>

class BImp;

class AImp : public BaseA
{
    public:
        AImp();
        virtual ~AImp();

    private:
        AImp(const AImp&);
        AImp& operator= (const AImp&);

    public:
        int MethodA(BaseB *param1) { return MethodA(reinterpret_cast<BImp *>(param1)); }

    private:
        int MethodA(BImp *param1);
};

class BImp : public BaseB
{
    public:
        BImp(std::string data1, std::string data2) : m_data1(data1), m_data2(data2) { }
        ~BImp();
        std::string m_data1;
        std::string m_data2;

    private:
        BImp();
        BImp(const BImp&);
        BImp& operator= (const BImp&);
};

Now, the problem is the fact that with this particular code, everything works perfectly. However, after i result in the destructor for BImp virtual, around the call to AImp::MethodA, the course BImp appears to possess its data (m_data1 and m_data2) uninitialized. I have checked making sure the contained information is correct at construction time, so I'm wondering what the explanation for this may be...

Cheers!

Edit: param1 was really a mention of the B in MethodA. Appears like I over-disinfected my real code a little an excessive amount of!

Edit2: Re-arranged the code a little to exhibit the 2 different files. Examined this code compiles, a properly. Sorry about this!

If you're casting between related types while you do within this situation, you should use [cde] or [cde], instead of static_cast, since the compiler may adjust the item pointer value while casting it to some more derived type. Caused by dynamic_cast is undefined within this situation, because you just need the pointer value and pretends it's another object with no regard for object layout.

MethodA got its parameters by value. What this means is a duplicate is passed (and also the copy needs to be destroyed). That's my best guess why you may have a BImpl being destroyed that you simply did not be prepared to be, however i aren't seeing exactly what the virtual or non-virtual character of A's destructor may have related to it.

But this code can't compile - you utilize class B in proclaiming the virtual function inside a, but B is not defined until later. And I'm not sure what's happening with this cast - you cannot reinterpret_cast class types. Possibly should you build up an evaluation situation which demonstrates your problem, and publish that?

There's lots of iffy stuff within this code, so I am amazed it works or compiles regardless.

  • Passing parameters by value rather than mention of the reinterpret_cast
  • Casting a reinterpret_cast to some MethodA via B -- bad idea! If you are likely to cast for the reason that direction, BImp may be the most secure.
  • I miss out on how you are supposed to obtain a BImp from a b -. You aren't invoking any constructors, and you've got none that may be invoked that will pay a B. Your default constructor for BImp is private, and setting a b - which has no data, casted to some BImp that also doesn't have data, to some BImp, still is not going to provide you with data!

Several comments:

  • Your base classes must have virtual destructors therefore the derived class' dtor is known as rather than the needed the bottom class dtor once the object is erased.

  • MethodA going for a BaseB pointer like a parameter only to achieve the pointer reinterpreted like a BImp (a derived class of BaseB) is harmful. There's no guarantee another thing apart from BImp is passed to MethodA. An amount happen if only a BaseB object ended up being to MethodA? Potentially plenty of bad things, I'd suspect.

  • I am speculating your code "works perfectly" since you only pass BImp to MethodA. If you're only passing BImp to MethodA make the signature match the intent (it has the additional advantage of getting rid of that awful reinterpret call).