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

В лекции Николы Гиганте в 2015 году, он упоминает (в начале), что в стандартной библиотеке нет чисто виртуальных функций (или он не знает о них). Я полагаю, что Алекс Степанов был против этой языковой функции, но с момента первоначального проектирования STL в библиотеку Standard проникли какие-либо чистые виртуальные программы?

FWIW (и поправьте меня, если я ошибаюсь) средства удаления в уникальных указателях в конечном итоге используют виртуальную диспетчеризацию в большинстве реализаций, но это не чистые виртуальные.


person Lorah Attkins    schedule 26.01.2016    source источник
comment
Вы имеете в виду всю Стандартную библиотеку или только часть STL (итераторы, алгоритмы и контейнеры)?   -  person Galik    schedule 27.01.2016
comment
Я не знаю ни одной чистой виртуальной функции в стандартной библиотеке. Удалители по умолчанию для unique_ptr очень невиртуальны, поэтому небезопасны, если вы выполняете приведение к неполиморфному базовому классу. shared_ptr, с другой стороны, сохраняет функцию удаления со стиранием типа с исходным указателем, так что это безопасно.   -  person Cheers and hth. - Alf    schedule 27.01.2016
comment
Любой класс, имеющий чисто виртуальную функцию, не может быть создан. Я не знаю каких-либо стандартных классов, которые предназначены только для использования в качестве базовых классов, а не для непосредственного использования.   -  person Mark Ransom    schedule 27.01.2016
comment
Я только вчера смотрел это! Я должен был прийти сюда и спросить. ;)   -  person erip    schedule 27.01.2016
comment
Я не слушал лекцию, но, похоже, она посвящена общему программированию и STL. Я подозреваю, что дело в том, что в C++ общее программирование, реализованное в STL, полностью ортогонально тому, что можно было бы считать типичными методами в объектно-ориентированном программировании.   -  person Galik    schedule 27.01.2016
comment
Именно такой вопрос возник у меня после прослушивания выступления ;)   -  person vsoftco    schedule 27.01.2016
comment
Вы хотите, чтобы он был указан как чисто виртуальный, или будет соответствовать конкретная реализация библиотеки std, использующая чисто виртуальные методы?   -  person Yakk - Adam Nevraumont    schedule 27.01.2016
comment
STL != Стандартная библиотека   -  person K-ballo    schedule 27.01.2016
comment
@ K-ballo Я думаю, что делаю очень четкое различие и использую только термин «Стандартная библиотека». STL правильно используется для обозначения библиотеки, разработанной Степановым и созданной в SGI.   -  person Lorah Attkins    schedule 27.01.2016
comment
@LorahAttkins: Вы подразумеваете, что STL предшествовала стандартной библиотеке. Это не совсем так: еще в 1995 году был значительный проект стандартной библиотеки, когда STL была объединена со стандартной библиотекой.   -  person MSalters    schedule 27.01.2016
comment
@MSalters Нет, не я. Я говорю, что Степанов, разработавший STL, не был поклонником виртуальных машин, так что эта часть стандартной библиотеки, скорее всего, была свободна от виртуальных; но с тех пор есть ли в stdlib (в целом - даже те части, которые произошли от STL и устаревших библиотек C - которые еще сложнее добавить новые стили) какие-либо виртуальные вызовы?   -  person Lorah Attkins    schedule 27.01.2016
comment
@MSalters значительный проект стандартной библиотеки еще в 1995 году был в основном стандартной библиотекой C.   -  person Lorah Attkins    schedule 27.01.2016
comment
@LorahAttkins: Нет, не было. Просто назову несколько частей, которые не являются производными от C и не являются частью STL: весь ‹iostream›, std::string, std::complex, исключения. Теперь std::string и std::complex, как правило, слишком критичны по времени для использования виртуальных функций, да и в этом нет необходимости - полиморфизм просто не нужен для простых значений. Но iostream и исключения используют виртуальные функции.   -  person MSalters    schedule 27.01.2016
comment
@MSalters Основные строительные блоки просто не используют настройку, основанную на переопределении виртуальных функций. Я подозреваю, что люди (как правило, Java-программисты стесняются final), которые делают многие функции виртуальными в фундаментальных конкретных классах (например, контейнерах), просто не смогут абстрактно указать, что значит переопределить эти функции и каким будет переопределение. разрешено делать.   -  person curiousguy    schedule 26.10.2019


Ответы (2)


[syserr.errcat.overview] имеет std::error_category

class error_category {
  virtual const char* name() const noexcept = 0;
  virtual string message(int ev) const = 0;
};

В C++14 других нет.

person Igor Tandetnik    schedule 27.01.2016
comment
Откуда ты знаешь, что других нет? Просто любопытно. (PS +1) - person Nemo; 27.01.2016
comment
@Nemo Искал текст стандарта, начиная с главы 17, для = 0. На глазок каждое попадание (их не так много). Веская причина откладывать выполнение реальной работы. - person Igor Tandetnik; 27.01.2016
comment
Обратите внимание, что типичная реализация std::function будет использовать чистые виртуальные функции в качестве детали реализации (или воспроизвести эквивалент с объектно-ориентированным программным обеспечением в стиле C). То же самое может быть верно для будущего и других типов стирания концепции/типа во время выполнения. - person Yakk - Adam Nevraumont; 27.01.2016
comment
Я предполагаю, что один вопрос здесь заключается в том, будет ли против стандарта, чтобы эти функции не были чисто виртуальными? (Будет ли какая-либо программа вести себя неправильно, если это так?) - person user541686; 27.01.2016
comment
@Mehrdad Я не понимаю, как это может привести к тому, что соответствующая программа перестанет работать. Однако это позволит принять несоответствующую программу — программу, имеющую класс, производный от std::error_category, который не может переопределить один из этих методов. Само по себе это можно было бы назвать несоответствием со стороны реализации - тот факт, что недопустимая программа принимается без диагностики. - person Igor Tandetnik; 27.01.2016

C++17 добавляет std::pmr::memory_resource в [mem.res.class] на на C+ +14 со следующими private чистыми виртуальными функциями:

class memory_resource {
    virtual void* do_allocate(size_t bytes, size_t alignment) = 0;
    virtual void do_deallocate(void* p, size_t bytes, size_t alignment) = 0;
    virtual bool do_is_equal(const memory_resource& other) const noexcept = 0;
};

И да, частные виртуальные функции можно переопределить.

person P.W    schedule 26.12.2018