Получить адрес базового объекта из производного объекта
Я получаю очень запутанную ошибку в моей программе. Я думаю, что у меня может быть два разных объекта одного и того же класса, где я думал, что у меня один и тот же объект. Это сбивает с толку, потому что я имею дело с очень большой структурой, где не просто получить указатель на нужный мне объект.
Мой вопрос: если у меня есть класс 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 и производные имеют один и тот же адрес.