Calling an assignment operator for one of the foundations with a vtables multilevel derived class in C ++

Okay, this is a little complicated. Here is the (simplified) code:

class A
{
    virtual ~A();
    // fields, none of which has an assignment operator or copy constructor
};

class B
{
    virtual ~B();
    // same as A
};

class Derived : public A, public B
{
    Derived();
    Derived(const B& b);
    // no fields
};

C Derived::Derived(const B& b)(i.e., taking one of its grounds) as follows

Derived::Derived(const B& b)
{
    *static_cast<B*>(this) = b;
    // Do other stuff with protected fields declared in B
}

For me, this is something in the line “just don't do it”, but that the existing code and we are experiencing subtle memory corruption are suspiciously next to this code. So I'm curious if this is good.

The curious part here is that both base classes have vtables, and none of them have explicit copy / assignment constructors / operators.

In my opinion, the memory layout for the class is Derivedas follows

 `Derived`
 ---------
 A-vtable
 A-fields
 B-vtable
 B-fields

, "B", B-vtable, , "A", A-vtable, vtables .

/ copy/assign B B-fields, *static_cast<B*>(this) = b; (static_cast B-fields, B-vtable , AFAIK).

, , , , . ? - , ( MSVC 2012 )?

: , / , . , , , , .

+4
2

, . . , , . :

this                     ->   | A-vtable |
                              | A-fields |
static_cast<B*>(this)    ->   | B-vtable |
                              | B-fields |

, , B Derived.


, , :

*static_cast<B*>(this) = b;

B, .. B::operator=(const B& other). , . :

B newObj = b;

Derived, B, :

Derived::Derived(const B& b) : B(b)
{
}
+1

?

Derived::Derived(const B& b)
: B(b)
{
}

:

Deriver& Derived::operator=(const Derived& rhs)
{
    A::operator=(rhs); //Assign A part
    B::operator=(rhs); //Assign B part
    //Derived-specific assignments

    return *this;
}

, , -.

, :

*static_cast<B*>(this) = b;

, . , , ( ).

, vtables. . :)

+1

Source: https://habr.com/ru/post/1614930/


All Articles