C++ Access derived class member from base class pointer

89,669

Solution 1

No, you cannot access derived_int because derived_int is part of Derived, while basepointer is a pointer to Base.

You can do it the other way round though:

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

Derived classes inherit the members of the base class, not the other way around.

However, if your basepointer was pointing to an instance of Derived then you could access it through a cast:

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

Note that you'll need to change your inheritance to public first:

class Derived : public Base

Solution 2

You're dancing on a minefield here. The base class can never know that it's actually an instance of the derived. The safest way to do that would be to introduce a virtual function in the 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;

If basepointer points as something other that a Derived, your program will die horribly, which is the intended result.

Alternatively, you can use dynamic_cast<Derived>(basepointer). But you need at least one virtual function in the Base for that, and be prepared to encounter a zero.

The static_cast<>, like some suggest, is a sure way to shoot yourself in the foot. Don't contribute to the vast cache of "unsafety of the C language family" horror stories.

Solution 3

you can use CRTP

you basically use the derived class in the template for the base class

Solution 4

It is possible by letting the base class know the type of derived class. This can be done by making the base class a template of derived type. This C++ idiom is called curiously recurring template pattern.

Knowing the derived class, the base class pointer can be static-casted to a pointer to derived type.

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

Solution 5

//if you know what derived class you are going to use

Derived* derivedpointer = dynamic_cast < Derived * > basepointer;

//then you can access derived class using derivedpointer

Share:
89,669

Related videos on Youtube

Peter
Author by

Peter

Updated on June 08, 2020

Comments

  • Peter
    Peter about 4 years

    If I allocate an object of a class Derived (with a base class of Base), and store a pointer to that object in a variable that points to the base class, how can I access the members of the Derived class?

    Here's an example:

    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?
    
  • NG.
    NG. over 14 years
    shouldn't he use dynamic_cast instead of static_cast?
  • Peter Alexander
    Peter Alexander over 14 years
    That depends whether or not he knows that it is a Derived or not. If you are 100% sure (as we are here) then static_cast is fine.
  • Soumya
    Soumya about 14 years
    "Alternatively, you can use dynamic_cast(basepointer). But you need at least one virtual function in the Base for that, and be prepared to encounter a zero." --> Good Point Seva.Liked It :)
  • Game_Overture
    Game_Overture over 12 years
    doesn't everyone mean reinterpret_cast instead of static_cast? I'm pretty sure static_cast won't compile.
  • David G
    David G about 9 years
    Using static_cast is not a way to shoot yourself in the foot. I think you're confusing it with C's explicit cast notation (T)x. static_cast on the other hand is type safe, but dynamic_cast will return a null pointer if it can't convert while static_cast will issue a compiler error.
  • Justin
    Justin almost 6 years
    @Balk No, static_cast is the correct thing here. reinterpret_cast would compile, but it does the wrong thing in many cases. reinterpret_cast does not change the address stored in the pointer, it just reinterprets it. However, static_cast sometimes needs to offset the pointer (e.g. if Derived inherited from multiple bases)
  • anurag86
    anurag86 almost 5 years
    Firstly you can't use dynami_cast unless you are dealing with polymorphic classes. This class(es) doesn't have any member functions to really add virtual behavior to it. static_cast is the best thing to do in the given scenario.