Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在派生类中使用私有抽象方法_C++_Inheritance - Fatal编程技术网

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

C++ 在派生类中使用私有抽象方法,c++,inheritance,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 { publi

我不理解以下限制:

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;
};
为什么我不能在派生类中使用基类的抽象虚拟私有方法而不重新声明它?这似乎是过于严格的限制,因为如果我使用了它,但没有定义它,那么
派生的
仍然是抽象的,要实例化它,一些进一步的派生类必须提供
doFoo


直觉上,我会说,通过不定义(或重新声明)方法,我意味着方法没有被使用,也不是派生类的一部分,但这对代码读者来说比编译器更重要。或者编译器也需要这些信息,这才是真正的原因?

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

私有基类函数不能在派生类方法中直接调用。然而,派生类的这种不可访问性与派生类的虚拟调用机制无关

在某些情况下,这是可取的。摘自《圣经》

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

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


如果要从派生类访问此方法,一个好方法是将其声明为受保护的

在这里,即使您没有将方法声明为
private
类的默认访问权限也是
private
。这意味着您隐式地将此方法声明为
private


(如果您使用的是
struct
,那么默认访问权限应该是
public

为什么不使用
受保护的
?我可能遗漏了一些东西这些是封装的基础。私密就是私密,就是这样。如果您作为一个类设计器想要向子类公开某些内容,请使用protected,如果您想要向所有客户机(以及本例中的子类)公开您的功能,请使用public.IMHO,私有虚拟方法没有多大意义。虚拟意味着可以被子类覆盖,私有意味着不能从基类访问。。。你的意思是受保护吗?@SergeBallesta进一步限制访问实际上是有用的。如果派生实现了doFoo,那么进一步的派生类将无法调用该实现。有了protected,他们就可以调用它了。然后
Derived
应该声明为
class-Derived:private-Base{…
。并且没有进一步的派生类将有权访问
派生的
类实现。但是在基类中使方法私有肯定会错过要点…嗯,这看起来真的像是一个XY问题。请确切地解释您正试图实现的内容。从本质上讲,链接下面说的是“复制代码”.我可以接受重新声明,但我真的想知道是否有更重要的原因,这不能立即生效(例如,编译器在需要时自行插入纯虚拟重新声明)。