Подтвердить что ты не робот

Почему виртуальная функция будет частной?

Я просто заметил это в некотором коде:

class Foo {
[...]
private:
    virtual void Bar() = 0;
[...]
}

Есть ли у этой цели какие-либо цели?

(Я пытаюсь перенести некоторый код из VS в g++, и это привлекло мое внимание)

4b9b3361

Ответ 2

Это чистая виртуальная функция, которая является частной. Это делает так, чтобы производный класс должен реализовать метод. В этом случае Bar.

Я думаю, вас может смутить b/c, это делается для создания "интерфейсов" на С++, и много раз люди думают об этом как о публичном. Бывают случаи, когда вы можете определить интерфейс, который является приватным, когда открытый метод использует эти частные методы, чтобы обеспечить порядок их вызова. (Я считаю, что это называется методом шаблонов)

Для относительно плохого примера:)

class RecordFile
{
    public:
       RecordFile(const std::string &filename);

       void process(const Record &rec)
       {
           // Call the derived class function to filter out
           // records the derived instance of this class does
           // not care about
           if (filterRecord(rec))    
           {
               writeRecordToFile(rec);           
           }
       };

    private:
       // Returns true if the record is of importance
       // and should be kept
       virtual bool filterRecord(const Record &rec) = 0;

       void writeRecordToFile(const Record &rec);
};

Ответ 3

ISO С++ 2003 явно разрешает это:

В разделе 10.3 ничего не говорится о спецификаторе доступа и содержит даже сноску во втором предложении, в котором говорится об ограничениях виртуальных функций:

[...] Контроль доступа (статья 11) не учитываются при определении наиважнейшая.

Код полностью закончен.

Ответ 4

Я приведу краткое объяснение из большой С++ FAQ Lite, которая суммирует ее хорошо:

[23.4] Когда кто-то должен использовать частный виртуалов?

Почти никогда.

Защищенные виртуальные машины в порядке, но частные виртуальные сети обычно являются сетью потеря. Причина: частные виртуальные путают новые программисты на C++ и путаница увеличивает стоимость, график задержек и ухудшает риск.

Новые программисты на C++ путаются частные виртуальные, потому что они думают, что приватный виртуальный не может быть переопределен. В конце концов, производный класс не может доступа к частным лицам базовый класс, так как, спрашивают они, могли бы переопределить виртуальный виртуальный базовый класс? Существуют объяснения выше, но это академическое. Реальная проблема в том, что почти все запутывается при первом запуске в частные виртуальные сети и путаницу плохо.

Если нет веской причины напротив, избегайте частных виртуальных машин.


С++ FAQ Lite был обновлен тем временем:

Кстати, это путает большинство начинающих программистов на C++, что частные виртуальные машины можно переопределить, не говоря уже о том, что они действительно действительны. Всех нас учили, что частные члены в базовом классе недоступны в классах, полученных из него, что является правильным. Однако эта недоступность по производному классу не имеет ничего общего с механизмом виртуального вызова, который относится к производному классу. Поскольку это может запутать новичков, часто задаваемые вопросы по С++, которые ранее использовались с использованием защищенных виртуальных машин, а не частных виртуальных машин. Однако частный виртуальный подход в настоящее время достаточно распространен, что путаница новичков не вызывает беспокойства.

Ответ 5

Обычный "академический" ответ: спецификаторы доступа и виртуальность ортогональны - один не влияет на другой.

Несколько практический ответ: частные виртуальные функции часто используются для реализации шаблона дизайна Template Method. В языках, которые не поддерживают частные виртуальные функции, метод шаблона должен быть общедоступным, хотя на самом деле он не должен быть частью интерфейса.

Ответ 6

Это чистая виртуальная функция. Любая конечная реализация, которая держится от "Foo", должна реализовывать функцию "Bar".

Ответ 7

Он делает функцию чистой виртуальной, а не виртуальной.

По умолчанию не реализована реализация, и намерение заключается в том, что реализация функции должна указываться наследующим классом. Однако это может быть переоценено.

Иногда вы видите полные классы, где все функции-члены задаются как виртуальные таким образом.

Это абстрактные базовые классы, иногда называемые классами интерфейсов, и разработчик ABC говорит вам: "Теперь я знаю, как эта функциональность будет реализована для всех специализаций этого базового класса. все они определены для вашей специализации для работы, и вы знаете, как должен вести себя ваш объект".

Изменить: Ой, просто заметили, что чистая виртуальная функция участника является частной. (Спасибо, Майкл) Это немного меняет ситуацию.

Когда этот базовый класс наследуется с помощью частного наследования, он меняет вещи. В основном то, что делает разработчик базового класса, заключается в том, что когда ваш производный класс вызывает не-частную функцию в базовом классе. часть поведения была делегирована вашей специализации функции в вашем производном классе. Не-частный член выполняет "что-то", и часть этого "чего-то" - это вызов через функцию чистого виртуального базового класса для вашей реализации.

Итак, какая-то публичная функция в Foo вызывает функцию Bar внутри Foo, и она полагается на то, что вы предоставите специализированную реализацию функции Bar для вашего конкретного случая.

Скотт Майерс ссылается на это как "реализованный в терминах".

Кстати, просто посмеиваясь о количестве ответов, которые были быстро удалены людьми, которые также не видели "мелкой печати" в вопросе! (-:

НТН

веселит,

Ответ 8

Единственная цель, которая, по-видимому, служит, - предоставить общий интерфейс.

Кстати, хотя функция объявлена ​​как виртуальная виртуальная, ее все еще можно реализовать и вызвать с помощью экземпляра класса или из друзей.

Тем не менее, подобные вещи обычно служат интерфейсом, но я этого не делаю.