If I allocate an ob开发者_JS百科ject 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?
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
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.
you can use CRTP
you basically use the derived class in the template for the base class
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();
}
//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
精彩评论