【问题标题】:Is there any difference between a private and protected pure virtual function?私有和受保护的纯虚函数之间有什么区别吗?
【发布时间】:2012-04-03 13:55:13
【问题描述】:

我可以理解,可能有理由将已实现的(与纯的)虚函数声明为私有或受保护的。 Afaik,如果您将实现的虚拟方法声明为受保护,您的子类可以调用基类的方法(而其他人不能)。如果将其声明为私有,则只有基类可以调用虚拟方法的默认实现。

但是,对于纯虚拟,没有基本实现......那么将纯虚拟声明为私有或受保护在功能上不等效吗?受保护的纯虚拟没有意义,因为您永远无法调用基类的相应方法。受保护的纯虚拟是否有任何意义?

关于 SO 有几个类似的主题,但我找不到任何能简明扼要地回答我的问题的内容。

【问题讨论】:

  • 你可以为接口实现friend
  • 纯虚方法可以有主体,可以像base::foo()一样显式调用。

标签: c++ inheritance pure-virtual


【解决方案1】:

是否有任何情况下受保护的纯虚拟会产生任何 有意义吗?

我认为您在这里的意思是私有的(而不是受保护的),但我想我理解您的意思。事实上,纯虚拟的访问类型可以在派生类中被覆盖。下面是一个示例,可以帮助您了解私有和受保护的纯虚拟之间的区别:

class Parent
{
  protected: virtual void foo() = 0;
  private:   virtual void bar() = 0;
  public:            void test() { foo(); bar(); }
};

class Child : public Parent
{
  public: void test2() { foo(); /* bar(); // cannot be called here */ }
};

class GrandChild : public Child
{
  // access types here can be anything for this example
  public: void foo() { cout << "foo" << endl; }
  public: void bar() { cout << "bar" << endl; }
};

【讨论】:

  • 感谢您的示例。澄清一下——一个私有的纯虚拟永远不能被它的任何后代调用(但可以由他们实现,所以基类可以调用它的后代的方法?)
  • 没有。在此示例中,如果 GrandChild 在其另一个方法中调用 foo(),它将按预期编译和工作,将调用 GrandChild::foo
  • 是的 Pris,一个虚函数可以被不同的访问类型覆盖,这可能会打开它的可访问性。
【解决方案2】:

第一个纯虚函数可以实现了!

#include <iostream>

class Animal
{
public:
  void eat(void);
protected:
  virtual void doEat(void)=0;
};
void Animal::eat(void)
{
  doEat();
}
void Animal::doEat(void)
{
  std::cout << "animal" << std::endl;
}

class Tiger : public Animal
{
private:
  virtual void doEat(void)
  {
    Animal::doEat();//here is the difference between protected and private
    std::cout << "tiger" << std::endl;
  }
};

int main(void)
{
  Animal *p = new Tiger();
  p->eat();
  return 0;
}

其次,Herb Sutter 解释了何时使用“virtual private”或“virtual protected”,您可以阅读此article。我认为这解释了为什么我们不仅可以这样做!文章说:“更喜欢使虚函数私有,只有派生类需要调用虚函数的基实现时,才使虚函数受保护”,你的问题是纯虚函数,我不太确定是否满足这个原则。

【讨论】:

    猜你喜欢
    • 2011-05-20
    • 2012-04-10
    • 2012-09-28
    • 2012-06-13
    • 1970-01-01
    • 2019-07-24
    相关资源
    最近更新 更多