在派生类中使用私有抽象方法

时间:2016-11-15 16:54:31

标签: c++ inheritance

我不明白以下限制:

class Base
{    
    virtual doFoo() = 0;
};

class Derived : public Base
{
public:
    void doStuff() { doFoo(); } //compile error, doFoo is a private member of Base    
};

解决方案当然是在派生类中重新声明成员,但对我来说似乎有些奇怪:

class Derived : public Base
{
public:
    void doStuff() { doFoo(); }

private:
    virtual doFoo() = 0;
};

为什么我不能在派生类中使用基类'抽象虚拟私有方法而不重新声明它?它似乎是过于严格的限制,因为如果我使用它但没有定义它,那么Derived仍然是抽象的并且为了实例化它,一些进一步的派生类必须提供doFoo

直观地我会说,通过不定义它(或重新声明它),我暗示该方法不被使用,并且不是派生类的一部分,但对于代码的读者而言,这比编译器更多。或者编译器也可能确实需要这些信息,这是真正的原因吗?

3 个答案:

答案 0 :(得分:3)

不能在派生类方法中直接调用私有基类函数。但是,派生类的这种不可访问性与虚拟调用机制没有任何关系,虚拟调用机制与派生类有关。

有些情况下这是可取的。取自C++ FAQ

  

您可能会问,派生类无法调用的方法有什么用?即使派生类不能在基类中调用它,基类也可以调用它,它有效地调用(适当的)派生类。这就是模板方法模式的全部内容。

     

想想“回到未来。”假设基类是去年编写的,您将在今天晚些时候创建一个新的派生类。几个月前可能已编译并插入库的基类方法将调用私有(或受保护)虚拟,并且将有效地“调用未来” - 几个月前编译的代码将调用代码那个甚至还不存在 - 你将在接下来的几分钟内编写的代码。您无法访问基类的私有成员 - 您无法进入过去,但过去可以到达未来并调用您尚未编写的方法。

答案 1 :(得分:2)

在派生类中声明新的成员函数不允许您访问基类中具有相同名称的函数。基类中的那个仍然是私有的,您无法从基类外部访问它(缺少朋友声明)。这与纯虚拟的成员函数无关;它适用于所有名称。如果您不希望它是私密的,请不要将其定义为私人。

答案 2 :(得分:0)

如果要从派生类访问此方法,一种好方法是将其声明为protected

此处,即使您未将该方法声明为privateclass的默认访问权限为private。这意味着您隐式将此方法声明为private

(如果您使用的是struct,则默认访问权限为public。)