Is a pointer allowed to change a value in a single inheritance?

I know that with multiple inheritance, the value of a pointer can be changed. But is this the case with one inheritance? Or with POD types for that matter?

You probably know a classic example:

#include <iostream>
using std::cout;
struct Base1 { virtual void f1() {} };
struct Base2 { virtual void f2() {} };
struct Derived : public Base1, public Base2 { virtual void g() {} };
int main() {
    Derived d{};
    auto *pd = &d;
    auto pb1 = (Base1*)pd;
    auto pb2 = (Base2*)pd;
    cout << pd << "\n"; // say, 0x1000
    cout << pb1 << "\n"; // say, 0x1000
    cout << pb2 << "\n"; // say, 0x1008 !!!
}

So far, so good, and this is a good old compiler practice. Objects are laid out in such a way that the "root" Base2has an offset to Derived, which can be printed when viewing the actual value of the pointer. This is not a problem if refrain from performing void*and reinterpret_casts.

And as far as I know in practice, this only happens with multiple inheritance.

: " "? POD?

+6
2

, . - , , .

( , - , ).

, , static_cast, reinterpret_cast ( reinterpret_cast, multiple static_cast void* ), .

POD - , , , PODness , .

, , 9.2:

, . , ( ).

[. , , , , . - ]

[. . - ]

, , , , 10:

, , .

+3

?

- , .

++ 11, :

4.10

3 " cv D", D , prvalue " cv B", B ( 10) D. B ( 11) (10.2) D, , , . . .

5.2.9

2 lvalue "cv1 B", B , , " cv2 D", D - ( 10) B, " D" " B" (4.10), cv2 cv-, cv-, cv1 B D, D. "cv2 D". "cv1 B" "rvalue reference to cv2 D" , lvalue "cv1 B". "cv1 B" D, D. undefined. [:

struct B { };
struct D : public B { };
D d;
B &br = d;
static_cast<D&>(br); // produces lvalue to the original d object

-end ]


class B { ... };
class D : public B { ... };

:

+------------------+
|  D members       |
+------------------+
|  B members       |
+------------------+

.

D d;
D* dptr = &d;
B* bptr = &d;

dptr bptr .

+2

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


All Articles