Is there any difference between a private and protected pure virtual function?
Asked Answered
P

2

24

I can understand that there might be a reason to declare an implemented (as opposed to pure) virtual function private or protected. Afaik, if you declare an implemented virtual method as protected, your child class can call the base class's method (and nobody else can). If you declare it private, than only the base class can call the default implementation of the virtual method.

However, with pure virtuals, there is no base implementation... So isn't it functionally equivalent to declare a pure virtual as either private or protected? A protected pure virtual doesn't make sense because you can't ever invoke the base class's corresponding method. Are there any scenarios where a protected pure virtual makes any sense?

There are a few similar topics on SO, but I couldn't find anything that concisely answered my question.

Papacy answered 19/3, 2012 at 1:57 Comment(2)
You can implement friend for interfaces.Kaneshakang
Pure virtual method can have body and it can be invoked explicitly like base::foo().Chefoo
M
11

Are there any scenarios where a protected pure virtual makes any sense?

I think that you mean private here (instead of protected), but think I understand your point. In fact, the access type of a pure virtual can be overridden in derived classes. Here's an example that might help you see the difference between a private and protected pure virtual:

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; }
};
Mazzola answered 19/3, 2012 at 2:31 Comment(3)
Thanks for the example. Just to clarify -- a private pure virtual can never be called by any of its descendants (but can be implemented by them, so the base class can invoke its descendant's method?)Papacy
No. In this example, if GrandChild called foo() inside another of its methods, it would compile and work as expected, GrandChild::foo would be called.Hialeah
Yes Pris, a virtual function can be overridden with a different access type that may open up it's accessibility.Mazzola
S
5

First pure virtual function can be implemented!

#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;
}

Second,Herb Sutter explained when to use "virtual private" or "virtual protected",you can read from this article.I think this explains why we do this not only we can!The article says:"Prefer to make virtual functions private,Only if derived classes need to invoke the base implementation of a virtual function, make the virtual function protected",your question is about pure virtual function,I am not quite sure whether satisfy this principle.

Sinfonia answered 23/1, 2013 at 9:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.