Если я выделяю объект класса Derived
(с базовым классом Base
), и хранят указатель на тот объект в переменной, которая указывает на базовый класс, как я могу получить доступ к членам 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* derivedpointer = new Derived;
derivedpointer->base_int; // You can access this just fine
Производные классы наследуют члены базового класса, а не наоборот.
Однако, если ваш базовый указатель
указывал на экземпляр Derived
, то вы могли получить к нему доступ через приведение:
Base* basepointer = new Derived;
static_cast<Derived*>(basepointer)->derived_int; // Can now access, because we have a derived pointer
Обратите внимание, что вам нужно изменить свое наследование на public
сначала:
class Derived : public Base
Вы танцуете здесь на минном поле. Базовый класс никогда не может знать, что он на самом деле является экземпляром производного. Самый безопасный способ сделать это - ввести виртуальную функцию в базу:
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
. Но для этого вам понадобится хотя бы одна виртуальная функция в Base
, и будьте готовы встретить ноль.
static_cast <>
, как некоторые предполагают, - верный способ выстрелить себе в ногу. Не пополняйте обширный тайник ужасных историй о "небезопасности семейства языков Си".