The difference that causes the virtual through the named element compared to the address or link

Updated below: In clang, using the lvalue of a polymorphic object through its name does not activate virtual dispatching, but does it at its address.

For the next base class Band derived D, virtual function something, unionSpace

#include <iostream>
using namespace std;

struct B {
    void *address() { return this; }
    virtual ~B() { cout << "~B at " << address() << endl; }
    virtual void something() { cout << "B::something"; }
};

struct D: B {
    ~D() { cout << "~D at " << address() << endl; }
     void something() override { cout << "D::something"; }
};

union Space {
    B b;
    Space(): b() {}
    ~Space() { b.~B(); }
};

If you have the value sof Space, in Clang ++: (update: it is incorrectly stated that g ++ has the same behavior) If you do s.b.something(), it is called B::something(), but does not perform dynamic binding on sb, however, if you call (&s.b)->something(), then dynamic binding to that will be performed that really contains B(either B, or D). Completion code:

union SpaceV2 {
    B b;
    SpaceV2(): b() {}
    ~SpaceV2() { (&b)->~B(); }
};

static_assert(sizeof(D) == sizeof(B), "");
static_assert(alignof(D) == alignof(B), "");

#include <new>

int main(int argc, const char *argv[]) {
    {
        Space s;
        cout << "Destroying the old B: ";
        s.b.~B();
        new(&s.b) D;
        cout << "\"D::something\" expected, but \"";
        s.b.something();
        cout << "\" happened\n";
        auto &br = s.b;
        cout << "\"D::something\" expected, and \"";
        br.something();
        cout << "\" happened\n";
        cout << "Destruction of D expected:\n";
    }
    cout << "But did not happen!\n";
    SpaceV2 sv2;
    new(&sv2.b) D;
    cout << "Destruction of D expected again:\n";
    return 0;    
}

-O2 :

$./a.out 
Destroying the old B: ~B at 0x7fff4f890628
"D::something" expected, but "B::something" happened
"D::something" expected, and "D::something" happened
Destruction of D expected:
~B at 0x7fff4f890628
But did not happen!
Destruction of D expected again:
~D at 0x7fff4f890608
~B at 0x7fff4f890608

, , s.b , something l- . , :

  • , new(&s.b) D undefined ++?
  • undefined, l- , - g++, Clang?

, S.O. -.

UPDATE , , : , s.b B, , s.b - "undefined ", , , . Space , , , . , , AFAIK. .

+4
1

new(&s.b) D; s.b B D.

s.b.something();. undefined, s.b B, , , D. . ++ 14 [basic.life]/7:

, , , , , , , , , , , , :

  • , ,

  • , ( cv- )

    [...]

, .

( , undefined, : ).

+2

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


All Articles