C ++ Доступный элемент classа из указателя базового classа

Если я выделяю объект classа Derived (с базовым classом Base ) и сохраняю указатель на этот объект в переменной, указывающей на базовый class, как я могу получить доступ к членам classа Derived ?

Вот пример:

 class Base { public: int base_int; }; class Derived : public Base { public: int derived_int; }; Base* basepointer = new Derived(); basepointer-> //Access derived_int here, is it possible? If so, then how? 

Нет, вы не можете получить доступ к derived_int потому что derived_int является частью Derived , а basepointer – указателем на Base .

Вы можете сделать это наоборот:

 Derived* derivedpointer = new Derived; derivedpointer->base_int; // You can access this just fine 

Производные classы наследуют членов базового classа, а не наоборот.

Однако, если ваш basepointer указатель указывал на экземпляр Derived вы можете получить к нему доступ через basepointer :

 Base* basepointer = new Derived; static_cast(basepointer)->derived_int; // Can now access, because we have a derived pointer 

Обратите внимание, что сначала вам нужно изменить свое наследование:

 class Derived : public Base 

Ты танцуешь на минном поле здесь. Базовый class никогда не может знать, что это фактически экземпляр производного. Самый безопасный способ сделать это – ввести виртуальную функцию в базу:

 class Base { protected: virtual int &GetInt() { //Die horribly } public: int base_int; }; class Derived : Base { int &GetInt() { return derived_int; } public: int derived_int }; basepointer->GetInt() = 0; 

Если basepointer указывает на что-то другое, что Derived , ваша программа умрет ужасно, что является предполагаемым результатом.

Кроме того, вы можете использовать dynamic_cast(basepointer) . Но для этого вам нужна хотя бы одна виртуальная функция в Base , и будьте готовы встретить нуль.

static_cast<> , как некоторые предлагают, является верным способом застрелить себя в ноге. Не вносите свой вклад в обширный кэш ужасных историй «небезопасности семейства языков Си».

вы можете использовать CRTP

вы в основном используете производный class в шаблоне для базового classа

Это возможно, если дать базовому classу знать тип производного classа. Это можно сделать, сделав базовый class шаблоном производного типа. Эта идиома C ++ называется любопытно повторяющимся шаблоном шаблона .

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

 template class Base { public: int accessDerivedField() { auto derived = static_cast(this); return derived->field; } }; class Derived : public Base { public: int field; }; int main() { auto obj = new Derived; obj->accessDerivedField(); } 

// если вы знаете, какой производный class вы собираетесь использовать

Производный * производныйpointer = dynamic_cast <Производный *> basepointer;

// тогда вы можете получить доступ к производному classу с использованием производного указателя

  • Значит ли размер указателей в C?
  • C: различия между указателем char и массивом
  • Что я могу использовать вместо оператора стрелки, `->`?
  • Дублирование объектов в Java
  • Почему полезен указатель «точка-volatile», например «volatile int * p»?
  • Почему не является законным преобразовывать «указатель на указатель на не-const» в «указатель на указатель на const»,
  • Преобразование из производного ** в базу **
  • Как эта ссылка осуществляется внутри страны?
  • Необходимость указателя на указатель
  • В чем разница между NULL, '\ 0' и 0
  • Назначения типа «auto» указателя в c ++ 11 требуют «*»?
  • Давайте будем гением компьютера.