在什么情况下继承私人成员会有用?

时间:2013-06-24 15:40:48

标签: c++

我无法理解为什么世界上任何人都想继承私人成员。

例如:

class Secretive {
    private: 
       int a;
    public:
       Secretive() { a = 0; }
    private: 
       int showSecret () { return a; };
};

class Curious:public Secretive 
{ ....  }

您能为我提供一个具体的例子,其中继承私有成员是有用的吗?你将如何访问这些私人会员?

6 个答案:

答案 0 :(得分:4)

私有成员函数实际上不是继承的,您无法在子类中访问它们。 (除非您使用重载的私有虚拟成员函数 - 在这种情况下,您也无法访问基类成员函数,但它仍然是继承,但它有其他用例)。

但无论如何,你想要它们在基类中,因为它们被基类中的其他私有/受保护成员函数使用(直接或以链式方式)。如果它没有被任何其他成员函数使用 - 那么你可以将它删除为未使用的代码。

同样在this article中,Herb Sutter建议并解释私人虚拟成员函数的使用。

答案 1 :(得分:1)

你肯定会有一个带有私有函数的基类,这些函数由派生类间接使用:

class Base
{
    private:
       int x;
    public:
       Base() : x(0) {}
       int func() { pfunc(); return x; }
    private:
       void pfunc() { x++; }
};


class Derived : public Base
{
 private:
   int y;
 public:
   Derived() y(2) {}
   int dfunc()  { return y + func(); }
};


... 

Derived d;
cout << "dfunc = " << d.dfunc() << endl;

这将打印3.

答案 2 :(得分:1)

私有成员用于实现类的不变。当您从具有不变量的类继承时,您可以访问该类的公共(和受保护)接口,以便无论如何都保持其不变量。如果关系的类型为 is-a 而不是 contains -a ,则您希望继承而不是简单地添加字段。

例如,你有一个Galaxians型游戏。您有一个基类GameObject,私有成员positionsprite,图形资源本身等;和公共成员movedraw ...

主船将是GameObject的子类,但是你不直接修改精灵,你将破坏基类所做的所有资源管理。相反,您可以像使用任何其他类一样使用公共接口。

你需要将主船作为GameObject的子类,以便它可以成为游戏列表的一部分。

答案 3 :(得分:1)

私有成员函数可以包含基本实现的公共接口使用的实用程序或公共功能。仅仅因为它们存在并不意味着它们适合派生类使用。

使成员变量私有允许访问器和增变器函数限制它们的使用方式以及成员变量可以容纳的值。例如,如果您的基类维护了一个指向对象的指针,并且您希望阻止该成员变量设置为nullptr

class FooBase
{
public:
    void setPointer(std::unique_ptr<int> ptr)
    {
        if(ptr.get() == nullptr)
        {
            // do something like throw an exception or set a default

        }
        else
        {
            var_ = std::move(ptr);
        }
    }

private:
    std::unique_ptr<int> var_;
};

答案 4 :(得分:1)

这类问题首先要考虑的是语言可能不尽如人意。特别是,不清楚继承代表什么对不同的人。

Curious类型的对象包含Secretive类型的子对象,而该对象又包含成员a。从这个意义上说,Curious确实包含a,因此它以某种方式继承它。

Curious完整对象无法直接访问a子对象中的Secretive子对象,因此有些人可能会说它 a {{1}成员。它存在但a无法实现。对于那些人Curious继承 Curious

为什么有人会在要扩展的类中将事物声明/定义为a

答案很简单,尽可能简单。出于完全相同的原因,您可以在其他地方创建任何其他内容privateprivate访问说明符用于标记作为实现详细信息的类型的成员,而不是在此特定类型之外使用,无论是完全不相关的还是派生类型都没有区别。

私人成员可以满足您的类型需求(不适用于其他人),private需要它们通过Secretive访问权限公开向所有或仅向派生类型公开的某些功能符。但是这些功能不会被其他任何人使用,并且在某些情况下它们可能会暂时中断您的类型的不变量。

考虑某种人为的例子,一种旨在以某种方式扩展的向量的实现。它可能具有指向所有(包含的派生类型)可访问的数据,大小和容量的指针,但不能从外部修改。它可能有protectedgrow_if_needmove_existing_elements使向量处于无效状态(不变量被破坏)但是当使用时(来自向量内的函数)从一个有效向量的状态到不同的有效状态。这些函数不应该在外部访问,就像它们打破不变量一样,但它们可以用来破坏和简化实现中的代码。

答案 5 :(得分:0)

您不能成为基类的私有成员。你可以用C ++覆盖它们,虽然我从来没有看到过这一点。

所以,回答你的问题:不,我不能举例说明你为什么要“继承”私人成员。