【问题标题】:How to access a private member in the baseclass from a subclass with inheritance ( C++ )如何从具有继承的子类访问基类中的私有成员(C++)
【发布时间】:2014-09-20 21:26:45
【问题描述】:

我目前正忙于继承,我正在使用一个名为Vehicle 的基类和一个名为Truck 的子类。子类继承自基类。我正在管理Vehicle 的公共成员的继承,但无法访问函数void describe() const 中名为top_speed 的私有成员。

我知道可以在代码中执行此操作(如下提供)以从基类进行访问,但似乎我遗漏了一些东西。在代码的注释部分中,我的问题更清楚地说明了您。

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

在我的Vehicle 类中它在哪里:

class Vehicle
{
private:
    double top_speed;

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

在卡车类中是这样的:

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

为了更清楚,我收到了这个错误:

error: 'double Vehicle::top_speed' is private

我可以在 void Truck::describe() const 函数中做什么来修复它?

【问题讨论】:

  • void Truck::describe() const : Vehicle() 不是有效的语法。无论如何,私有的重点是成员不暴露给派生类。有一个完全独立的访问说明符。
  • 简单来说,你不能从一个类访问私有成员到另一个类。
  • 如果你想做意大利面,你也可以在 Vehicle 课堂上 friend class Truck;。 (即不要)。
  • 我希望你知道Truckdescribe不会覆盖Vehicle的。

标签: c++ class inheritance private members


【解决方案1】:

只需声明top_speedas protected

class Vehicle
{
protected:
    double top_speed;

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

如果你不能修改基类,那么你就不能访问它。

【讨论】:

  • 是的,我试过了,效果很好,但我不能更改给定的 Vehicle 类。
  • @Joe_B 好的,如果没有 getter 或其他方式暴露来获取属性,那么您将无能为力。
  • @Joe_B 我不知道你应该用它做什么,但你可以使用基类描述函数来做你需要的事情吗?如果这和你的代码一样简单,比如输出。
【解决方案2】:

最简洁的方法是在基类中使用公共访问器函数,返回当前值的副本。您要做的最后件事是将私有数据暴露给子类(*)。

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

然后像这样在 Truck 类中使用它:

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

(是的,我知道,“this->”是多余的,但它用于说明它正在访问类的成员/方法)

(*) 因为,真的,如果你要公开超类的数据成员,那你为什么要使用 private/protected/public?

【讨论】:

  • 公共吸气剂只不过是封装的错误幻觉。 getter 只比 public 成员稍微好一点。
  • @LuchianGrigore,当它不与公共二传手配对时,它肯定有更多优点。
  • 我同意,但在某些时候你确实需要访问保存在基类中的信息;您所有车辆的“公共 API”。没有访问权限,几乎没有人可以处理这些信息。使其成为公共 getter 至少是一种向外界公开信息的安全方式。
  • 这完美!太感谢了。我只是想使用 getter 和 setter。
  • @Joe_B,我不允许更改给定的 Vehicle 类。
【解决方案3】:

Joe_B 说

我不允许更改给定的 Vehicle 类

然后,仍然有一种非常棒的方法可以访问您无法修改的类的私有成员(例如第 3 方)。

如果 verhicle.h(假设这是您无法修改的类)是:

class Vehicle
{
private:
    double top_speed;

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

而卡车.h 是:

#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;
    }
};

编译会报错

Vehicle::top_speed 是私有的

然后,让我们这样做:

在trunk.h中,将#include "vehicle.h"改成:

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

在不修改vehicle.h 的情况下,您使Truck 类成为Vehicle 类的朋友,它现在可以访问Vehicle 的私有成员!

请不要评论说这样做是一个非常糟糕的主意,因为它违反了所有 C++ 规则....我知道,您只想在以下情况下这样做:

  • 您确实需要访问私有成员并且别无选择
  • 真的没有办法不能修改vehicle.h
  • 您肯定知道自己在做什么,因为如果编写 Vehicle 的人将此属性设为私有,很可能是因为他不想让您访问它...

过去我在自定义一些 MFC 类的行为时经常这样做……我绝对无法更改定义它们的头文件……

【讨论】:

  • 多么棘手的方法!这是否适用于多个私有声明或任何包含在此之前可能包含“清洁车辆”标头的层次结构?
  • 如果有多个 private: 声明,GNU 编译器只会发出警告(说 class 已经是朋友),pragma 可以轻松删除它。拥有其他清洁车辆不应该引起任何问题。请注意,Truck 也成为 vehicle.h 包含的所有类的朋友(并使用 private: 关键字)。我也喜欢这个技巧(当我使用它时为它感到自豪......),如果你喜欢它,请投票;-)
猜你喜欢
  • 1970-01-01
  • 2013-02-12
  • 2017-03-16
  • 1970-01-01
  • 2017-04-14
  • 2013-04-11
  • 2016-01-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多