简体   繁体   中英

How to access a private member in the baseclass from a subclass with inheritance ( C++ )

I am currently busy with inheritance and I'm working with a base class called Vehicle and a subclass called Truck . The subclass is inheriting from the base class. I am managing with the inheritance of the public members of Vehicle but can't access the private member called top_speed in the function void describe() const .

I know that one can do this in code (provided below) to access from the base class but it seems like I'm missing something. In the comment section in the code my question is stated more clearly for you.

void Truck::describe() const : Vehicle()  

/*I know this is a way->    : Vehicle() 
to inherit from the Vehicle class but how
can I inherit the top_speed private member of Vehicle in the
void describe() const function of the Truck class?*/

{
    cout << "This is a Truck with top speed of" << top_speed << 
    "and load capacity of " << load_capacity << endl;
}

Where in my Vehicle class it is:

class Vehicle
{
private:
    double top_speed;

public:
    //other public members
    void describe() const;
};

and in the Truck class it is this:

class Truck: public Vehicle
{
private:
    double load_capacity;
public:
    //other public members
    void describe() const;  
};

To be even more clear I am getting this error:

error: 'double Vehicle::top_speed' is private

What can I do in the void Truck::describe() const function to fix it?

Simply declare top_speed as protected

class Vehicle
{
protected:
    double top_speed;

public:
    //other public members
    void describe() const;
};

If you can't modify the base class then you just can't access it.

The cleanest way is to have a public accessor function in the base class, returning a copy of the current value. The last thing you want to do is expose private data to subclasses(*).

double Vehicle::getTopSpeed( void ) const {
    return this->top_speed;
}

and then use it in the Truck class like this:

void Truck::describe( void ) const {
   cout << "This truck's top speed is " << this->getTopSpeed() << endl;
}

(Yeah, I know, "this->" is superfluous but it's used for illustrating that it's accessing members/methods of the class)

(*) Because, really, if you're going to expose data members of superclass(es), then why would you use private/protected/public at all?

Joe_B said

I am not allowed to make changes to the Vehicle class given

Then, there is still a very hugly way to access private members of a class you cannot modify (3rd party for instance).

If verhicle.h (let's say that's the class you have no way to modify) is:

class Vehicle
{
private:
    double top_speed;

public:
    Vehicle( double _top_speed ) : top_speed( _top_speed ) {}
};

and truck.h is:

#include "vehicle.h"
class Truck: public Vehicle
{
private:
    double load_capacity;

public:
    Truck( double _load_capacity, double _top_speed ) : 
        Vehicle( _top_speed ), 
        load_capacity( _load_capacity ) 
    {}

    void describe() const
    {
        std::cout << "This is a Truck with top speed of " 
                  << top_speed 
                  << " and load capacity of " 
                  << load_capacity 
                  << std::endl;
    }
};

Compiling this will give the error

Vehicle::top_speed is private

Then, let's do this:

In trunk.h, change #include "vehicle.h" into:

#define private friend class Truck; private
#include "vehicle.h"
#undef private

Without modifying vehicle.h, you made Truck class be a friend of Vehicle class, and it can now access Vehicle's private members!

Please, do not comment that it is a very bad idea to do this as it breaks all C++ rules....I know, you only want to do this if:

  • You really need to access a private member and have no alternative
  • There's really no way you cannot modify vehicle.h
  • You definitely know what you are doing, because if the guy who coded Vehicle made this attribute private, it was most likely because he did not want you to access it...

I used to do this when customizing behaviour of some MFC classes in the past...I definitely could not change the header files defining them....

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM