Получить адрес базового объекта из производного объекта

Я получаю очень запутанную ошибку в моей программе. Я думаю, что у меня может быть два разных объекта одного и того же класса, где я думал, что у меня один и тот же объект. Это сбивает с толку, потому что я имею дело с очень большой структурой, где не просто получить указатель на нужный мне объект.

Мой вопрос: если у меня есть класс Derived, который наследуется от Base, и у меня есть указатель на объект Derived, как я могу получить адрес объекта Base из производного объекта? Я работаю с исходным кодом базового класса и распечатываю адрес "this" в Base. В другой части моего кода получить указатель на производное. Мне нужно иметь возможность печатать адрес базового объекта через мой производный объект, чтобы определить, есть ли у меня указатель на конкретный производный объект, который мне нужен.

У меня может быть большое недопонимание того, как адреса работают в C++ при наследовании. Возможно, это всего лишь один объект, а не базовый объект, связанный с производным объектом?

большое спасибо

Изменить: причина, по которой я хочу сделать это исключительно для отладки. Проблема в том, что используемая кодовая база не содержит много интерфейсов или защищенных членов, поэтому мне приходится редактировать исходный код, чтобы получить доступ к определенной части информации. Однако моя программа падает, когда я вызываю метод, который я добавил в базовый класс, используя определенный указатель Derived. Мне нужно иметь возможность напечатать адрес базового объекта в этом случае, чтобы я мог определить, является ли это правильный объект или я получаю эту ошибку, потому что у меня фактически есть указатель на неправильный объект. Я понимаю, что могу добавить код в производный класс, чтобы заставить его печатать свой адрес, но мне было просто интересно, можно ли получить адрес без редактирования исходного кода. Спасибо

3 ответа

Переход от указателя на производный класс к указателю на базовый класс очень прост:

Derived * derived_ptr = < some pointer >;
Base * base_ptr = derived_ptr;

Если вы хотите быть педантичным, вы можете использовать static_cast на правой стороне задания:

Base * base_ptr = static_cast<Base*>(derived_ptr);

Переход от указателя на базовый класс к указателю на производный класс использует dynamic_cast:

Derived * derived_ptr = dynamic_cast<Derived*>(base_ptr);

Тем не менее, это не всегда работает. Вам необходимо включить typeid во время выполнения, а в базовом классе должен быть хотя бы один виртуальный метод.

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

Существует только один объект, он состоит из базы и производного, то есть база в большинстве реализаций помещается в память прямо рядом с производным. Это означает, что Base* не совпадает с Derived* в общем случае, но они будут очень близки.

Теперь вы можете тривиально получить Base* из Derived*, приведение неявно, но вы также можете сделать его явным:

Derived* dptr = ...;
Base* ptr = dptr;

Однако ничто не мешает одному производному объекту содержать несколько Base объекты. Обычно это не так, но это может случиться. Это означает, что вы не можете сравнить Base указатели и ожидают знать, если вы имеете дело с тем же объектом, только с тем же Base субобъект.

В простом случае одиночного наследования с большинством компиляторов:

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

В памяти, если вы создадите экземпляр производного класса, он будет размечен как члены базового объекта, за которым следуют члены производного объекта. Члены базового класса являются частью производного объекта.

class Base
{
   int b;
};

class Derived : public Base
{
   int d;
};

В памяти скажем, что производный указатель - 0400. Тогда:

0400 byte 1 of b
0401 byte 2 of b
0402 byte 3 of b
0403 byte 4 of b
0404 byte 1 of d
0405 byte 2 of d
0406 byte 3 of d
0407 byte 4 of d

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

Так уж сложилось, что в 0400 находится базовая часть объекта производного. Итак, base и производные имеют один и тот же адрес.

Другие вопросы по тегам