我可以在派生类中继承私有成员吗?

Can I subclass private members in a derived class?

本文关键字:成员 继承 派生 我可以      更新时间:2023-10-16

我有一个基本数据成员类:

class DataClass {
}

和子类:

class DerivedDataClass : public DataClass {
}

我使用DataClass作为类DataClassList的私有成员

class DataClassList {
  public:
    // some useful functions here
  private:
    DataClass private_data;
}

我想子类化DataClassList来创建一个类,可以对DerivedDataClass操作

class DerivedDataClassList : public DataClassList {
  // how do i get this class to use DerivedDataClass as the private member?
}

这可以在c++中以某种形式完成吗?

编辑:添加更多关于我正在尝试做的事情的注释:

DataClass有一些有用的函数,我不想在DerivedDataClass中重新定义,DerivedDataClass有自己的函数。所以,继承是有意义的。到目前为止一切都很好。

下一层才是问题所在。DataClassList具有依赖于DataClass函数的有用函数。DerivedDataClassList将需要从DerivedDataClass 访问数据/运行函数,除了基类提供的有用函数。

如果不能将DataClassList中的私有DataClass成员更改为DerivedDataClass,则无法从DerivedDataClassList中调用DerivedDataClass中的函数。

基本上,你没有。Private的意思是私有的——它只属于那个类。正确的方法是使用访问器函数。

如果这个类访问那个成员有一个特殊的要求,那么它应该被保护[然而,这是一个相当愚蠢的概念,因为它根本没有提供任何保护——任何想要访问那个字段的人都只需要从这个类派生,瞧,他们有自由访问权]。

感谢jogojapan指出我错过了一点。使用模板是一种解决方案。另一种方法是在基类中使用指针,然后让一个访问器函数将private_data设置为所提供的类成员。哪个是"正确的"取决于你想做什么。例如,如果它是某种类型的元素列表(例如图形对象(Window, Menu等)或游戏对象),并且你实际上希望它们是一个列表[或几个类似的列表],那么使用指针是正确的解决方案。如果您有几种不同的、不同类型的对象,而这些对象从未以一种常见的方式使用过,那么模板类可能是正确的选择。

一旦您为此使用继承,您将从基类获得private_data成员作为派生类的成员,尽管是不可访问的成员。不能在派生类中更改基类成员的数据类型。

我相信在你的情况下使用类模板更好:

template <typename Data>
class DataClassList
{
public:
  /*...*/
private:
  Data private_data;
};

您只需要编写上面的定义一次,但是您可以像下面这样创建实例:

DataClassList<DataClass>         standard_list;
DataClassList<DerivedDataClass>  derived_list;

前者是包含DataClass成员的对象,后者是包含DerivedDataClass成员(不包含其他成员)的对象。

我假设你想在DerivedDataClassList中使用DataClass对象private_data。如果你想使用DerivedDataClass,那么你需要在某个地方声明一个DerivedDataClass的对象(我在任何地方都没有看到DerivedDataClass的对象)。或者你需要从DerivedDataClass继承-我再次在你的代码中没有看到。

class DataClassList 
{
    protected:
        DataClass private_data;
};
class DerivedDataClassList : private DataClassList 
{
    // DataClass object private_data is like a private member here
};

如果你让private_data成为DataClassListprotected成员而不是private,让DataClassList成为DerivedDataClassListprivate base class成员,那么private_data就像DerivedDataClassListprivate成员。

如果你原来的问题没有输入错误,你实际上想要DerivedDataClass对象作为私有成员,那么你可以使用指针。

class DataClassList 
{
    public:
        DataClassList(DataClass * p) : private_data(p) {}
    protected:
        DataClass * private_data;
};
class DerivedDataClassList : private DataClassList 
{
    public:
    DerivedDataClassList():DataClassList(new DerivedDataClass) { }
    // private_data which a pointer to a DerivedDataClass object is like a private member here. 
};