Почему указатели на один и тот же объект имеют разные значения?

У меня есть эта часть кода:

#include <iostream>

class A
{
public:
    A() : m_i(0) { }
protected:
    int m_i;
};
class B
{
public:
    B() : m_d(0.0) { }
protected:
    double m_d;
};
class C : public A, public B
{
public:
    C() : m_c('a') { }
private:
    char m_c;
};

int main()
{
    C d;
    A *b1 = &d;
    B *b2 = &d;

    std::cout << (long)b1 << std::endl <<(long)b2<< std::endl;
}

при компиляции и запуске он производит следующий вывод:

140734705182320
140734705182328

Не совсем понятно, почему разные указатели на один и тот же адрес (& d) имеют разные значения.

заблаговременно.

Ответ 1

Макет памяти объекта C будет выглядеть примерно так:

A base_object_1;
B base_object_2;
char m_c;

Два базовых объекта имеют разные адреса; A будет (обычно) иметь тот же адрес, что и полный объект, но B будет (как правило, нет). Конечно, они не могут иметь один и тот же адрес друг друга, если только хотя бы один из них пуст.

Поэтому преобразование указателя в полный объект в указатель на один из базовых объектов должно изменить значение указателя, чтобы указать правильный адрес.