Pergunta

Se eu alocar um objeto de um Derived classe (com uma classe base de Base), e armazenar um ponteiro para esse objeto em uma variável que aponta para a classe base, como posso acessar os membros da classe Derived

Aqui está um exemplo:

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?
Foi útil?

Solução

Não, você não pode acessar derived_int porque derived_int faz parte de Derived, enquanto basepointer é um ponteiro para Base.

Você pode fazê-lo de outra maneira, porém:

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

As classes derivadas herdam os membros da classe base, não o contrário.

No entanto, se o seu basepointer estava apontando para uma instância de Derived então você pode acessá-lo através de um elenco:

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

Note que você vai precisar para mudar a sua herança para public primeiro:

class Derived : public Base

Outras dicas

Você está dançando no campo minado aqui. A classe base nunca pode saber que ele é realmente uma instância do derivado. A maneira mais segura de fazer isso seria a introdução de uma função virtual na 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;

Se os pontos basepointer como algo que uma Derived, o programa irá morrer horrivelmente, que é o resultado pretendido.

Como alternativa, você pode usar dynamic_cast<Derived>(basepointer). Mas você precisa de pelo menos uma função virtual no Base para isso, e estar preparado para encontrar um zero.

O static_cast<>, como alguns sugerem, é um caminho certo para atirar no próprio pé. Não contribuem para a grande esconderijo de "insegurança dos familiares linguagem C" histórias de horror.

Você pode usar CRTP

Você basicamente usar a classe derivada do modelo para a classe base

É possível, deixando a classe base sabe o tipo de classe derivada. Isso pode ser feito, fazendo o modelo de uma classe base do tipo derivado. Esta linguagem C ++ é chamado curiosamente recorrente padrão de modelo .

Conhecendo a classe derivada, o ponteiro classe base pode ser estático-escalado para um ponteiro para tipo derivado.

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();
}

// se você sabe o derivado classe que você está indo para uso

Derivado * derivedpointer = dynamic_cast basepointer;

// então você pode acessar classe derivada usando derivedpointer

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top