Подтвердить что ты не робот

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

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?
4b9b3361

Ответ 1

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

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

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

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

Однако, если ваш basepointer указывал на экземпляр 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

Ответ 2

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

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). Но для этого вам нужна хотя бы одна виртуальная функция в базе, и будьте готовы встретить нуль.

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

Ответ 3

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

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

Ответ 4

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

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

template<typename DerivedT>
class Base
{
public:
    int accessDerivedField()
    {
        auto derived = static_cast<DerivedT*>(this);
        return derived->field;
    }
};


class Derived : public Base<Derived>
{
public:
    int field;
};

int main()
{
    auto obj = new Derived;
    obj->accessDerivedField();
}

Ответ 5

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

Производный * производныйpointer = dynamic_cast < Производный * > базовый указатель;

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