Используя указатель A*
, возвращаемый упомянутой вами функцией, никаких настроек нет: это уже A*
, он указывает непосредственно на объект A
, который может быть подобъектом базового класса A
B
объект.
Однако в логике возврата функции, о которой вы упоминаете, может и обычно будет корректировка значения указателя , которая выдает A*
, указывающий на B
object.
Это потому, что B
обычно будет иметь указатель vtable в начале, так что подобъект базового класса A
не имеет смещения 0. Необходимая регулировка позволяет испортитьэффективно делая reinterpret_cast
, который не корректируется.И это может произойти с простым умом для удаления для unique_ptr
(a shared_ptr
умнее, по какой-то цене).
Пример:
struct A
{
int x;
};
struct B: A
{
virtual void foo(){}
B( const int value ): A{ value } {}
};
B b_object( 42 );
auto ptr()
-> A*
{
return &b_object;
}
#include <iostream>
auto main()
-> int
{
using namespace std;
cout << "&b_object = " << &b_object << ".\n";
cout << "As A* it's = " << ptr() << ".\n";
cout << b_object.x << " in B, is " << ptr()->x << " in A.\n";
}
Результат с MinGW g ++ 7.3.0 в Windows 10:
&b_object = 0x512030.
As A* it's = 0x512038.
42 in B, is 42 in A.
По адресам видно, что дополнительная информация в начале B
составляет 8 байт, что соответствует 8-значение байтового указателя для этого 64-битного компилятора.