0

我无法理解为什么世界上会有人想要继承私有成员。

例如:

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

class Curious:public Secretive 
{ ....  }

你能给我一个具体的例子,在这个例子中继承私有成员很有用吗?您将如何访问这些私人成员?

4

6 回答 6

4

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

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

同样在这篇文章中, Herb Sutter 建议并解释了私有虚拟成员函数的使用。

于 2013-06-24T15:50:16.740 回答
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。

于 2013-06-24T15:51:18.680 回答
1

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

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

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

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

于 2013-06-24T15:51:32.963 回答
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_;
};
于 2013-06-24T15:55:19.677 回答
1

对于这类问题,有些人首先想到的是语言可能不够清晰。特别是,尚不清楚遗传对不同的人代表什么。

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

完整的Curious对象不能直接访问a子对象内部的Secretive子对象,所以有人可以说它没有成员a。它在那里,但从Curious. 对于那些Curious有继承权 a的人。

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

答案很简单,就这么简单。出于完全相同的原因,您可以在其他任何地方制作其他private任何东西。访问说明符用于标记作为实现细节的类型的private成员,而不是在此特定类型之外使用,无论是完全不相关的类型还是派生类型都没有区别。

私有成员的存在是为了满足您的类型需求(而不是其他类型),它们是某些功能所需要的,这些功能通过访问说明符Secretive公开给所有或仅对派生类型公开。protected但是这些函数不能被其他任何人使用,并且在某些情况下它们可能会暂时破坏您类型的不变量。

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

于 2013-06-24T15:55:53.580 回答
0

你不能是基类的私有成员。不过,您可以在 C++ 中覆盖它们,尽管我从来没有看到这一点。

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

于 2013-06-24T15:51:47.653 回答