Знам, че при множествено наследяване стойността на указателя може да се променя. Но такъв ли е случаят и с единичното наследяване? Или с POD видове за този въпрос?
Вероятно знаете класическия пример:
#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 !!!
}
Дотук добре и това е добрата стара компилаторска практика. Обектите са разположени по начин, по който "коренът" на Base2
има отместване до Derived
, което може да бъде отпечатано, когато се гледа действителната стойност на показалеца. Това не е проблем, когато се въздържате от извършване на void*
и reinterpret_cast
s.
И доколкото знам на практика това се случва само при множествено наследяване.
Но въпросът ми: Какво казва стандартът за „промяна на стойности на показалеца по време на прехвърляне“? Може ли това да се случи само с множествено наследяване или може да се случи и с единично наследяване или предаване на POD?
struct Base1 { int x; }; struct Derived : Base1 { virtual void f(){} };
. - person Raymond Chen   schedule 25.02.2017