Есть ли разница между закрытой и защищенной чисто виртуальной функцией? - PullRequest
18 голосов
/ 19 марта 2012

Я могу понять, что может быть причина объявить реализованную (в отличие от чистой) виртуальную функцию частной или защищенной. Afaik, если вы объявите реализованный виртуальный метод как защищенный, ваш дочерний класс может вызвать метод базового класса (и никто другой не сможет). Если вы объявите его закрытым, то только базовый класс может вызвать реализацию виртуального метода по умолчанию.

Однако для чистых виртуальных компьютеров базовая реализация отсутствует ... Так разве не функционально эквивалентно объявлять чистый виртуальный объект частным или защищенным? Защищенный чистый виртуал не имеет смысла, потому что вы никогда не сможете вызвать соответствующий метод базового класса. Существуют ли сценарии, когда защищенный виртуальный имеет смысл?

Есть несколько похожих тем по SO, но я не смог найти ничего, что бы кратко отвечало на мой вопрос.

Ответы [ 2 ]

8 голосов
/ 19 марта 2012

Существуют ли сценарии, где защищенный чистый виртуал имеет какой-либо смысл?

Я думаю, что вы имеете в виду здесь личное (а не защищенное), но, кажется, я понимаю вашу точку зрения.Фактически, тип доступа чистого виртуального может быть переопределен в производных классах.Вот пример, который может помочь вам увидеть разницу между частным и защищенным чисто виртуальным:

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; }
};
4 голосов
/ 23 января 2013

Первая чисто виртуальная функция может быть реализована!

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

Во-вторых, Херб Саттер объяснил, когда использовать «виртуальный частный» или «виртуально защищенный», вы можете прочитать из этой статьи Я думаю, это объясняет, почему мы делаем это не только мы! В статье говорится: «Предпочитаю делать виртуальные функции частными, только если производные классы должны вызывать базовую реализацию виртуальной функции, делать виртуальную функцию защищенной», ваш вопросо чистой виртуальной функции, я не совсем уверен, удовлетворяю ли этот принцип.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...