C acesso ++ derivada membro da classe de ponteiro classe base
-
19-09-2019 - |
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
/ p>
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?
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
// então você pode acessar classe derivada usando derivedpointer