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

С++: Альтернатива STL и Boost?

С++ - это язык с несколькими парадигмами и STL и Boost построены по функциональной парадигме языка. STL состоит из контейнеров (для хранения данных), итераторов (для доступа к данным) и алгоритмов (функций для управления данными). Алгоритмные функции применяются к контейнерам с помощью итераторов. В качестве побочного эффекта эти методы не являются частью классов контейнеров, но полностью разделены. (Это позволяет избежать избыточности для библиотек, но это больно для пользователей библиотеки.)

Существуют ли альтернативы С++ для STL/Boost, которые предлагают такие контейнеры в более традиционном объектно-ориентированном вкусе? Я ищу строки, векторы, связанные списки, карту, деревья, хэш-таблицы и т.д. Контейнеры должны быть легко унаследованы и распространены. Для сравнения, расширение классов из STL/Boost - это очень плохая идея, и это по дизайну их дизайнеров.

PS: Пожалуйста, не используйте пространство ответов ниже, чтобы продемонстрировать преимущества STL/Boost. Я им хорошо знаком!: -)

4b9b3361

Ответ 1

Взгляните на Qt4, я всегда был его поклонником.

обновила ссылку.

Ответ 2

Многие (большинство!) старых библиотек для С++ использовали контейнеры, которые были гораздо ближе к тем, которые используются в таких вещах, как Java и С#.

Несколько примеров таких библиотек включают COOL, ET ++, Библиотека классов NIH и Rogue Wave Tools.h ++.

Две точки:

  • В лучшем случае это источник, если вдохновение. Я почти уверен, что это было не менее 10 лет (и часто больше, чем 20), поскольку любой из них был обновлен. Там практически нет никаких шансов, что любой из них даже будет компилироваться с любым разумным текущим компилятором.
  • Я хочу пойти на запись, указав, что я предоставляю ссылки на них только в ответ на очень конкретный вопрос. Я, конечно же, не рекомендую использовать какой-либо из приведенных выше кодов, а также не рекомендую использовать их в качестве вдохновения.

Конечно, я здесь ясен, по крайней мере, ИМО:

  • Обвинения в вашем вопросе совершенно ложны.
  • То, что вы пытаетесь сделать, абсолютно безумное!
  • Вы тратите свое время.
  • Написание кода таким образом - действительно, очень плохая идея. Просто скажи нет!
  • Если вы настаиваете на этом, вы станете парией.
    1. Даже не-программисты, которые не совсем понимают, почему, начнут сильно ненавидеть вас.
    2. Ваша собака будет использовать вашу обувь и кровать в качестве своего туалета.

Ты сам по себе. Вы были предупреждены!

Закрытые субтитры для ослабленного юмора: конечно, некоторые из них предназначены для юмористики - действительно, действительно паршивая идея, хотя

Ответ 3

Это позволяет избежать избыточности для библиотеки писателей, но больно для библиотеки пользователей.

Я не согласен с этой предпосылкой. И даже если бы я это сделал, это огромное чрезмерное обобщение, которое не распространяется на каждого пользователя библиотеки. Но в любом случае это субъективное утверждение, поэтому я проигнорирую его.


Существуют ли альтернативы С++ для STL/Boost, которые предлагают такие контейнеры в более традиционных объектно-ориентированных аромат?

...

Контейнеры должны иметь методы, которые позволять им манипулировать ими непосредственно. (Например, вызов vector.sort() вместо сортировать (vector.begin(), vector.end()).

Конечно. Просто создайте свои собственные контейнеры, которые имеют стандартные контейнеры в качестве элементов данных и делегируют их вызовы и алгоритмы по мере необходимости через функции-члены. Это довольно тривиально:

template<typename T>
class MyVector
{
public:
    void sort()
    {
        std::sort(vec.begin(), vec.end());
    }

    // ...
private:
    std::vector<T> vec;
};

Нет ничего в С++, который мешает вам делать что-то подобное, по иронии судьбы благодаря многопарадигматической природе С++, с которой вы, похоже, не согласны.

Возможно, вы можете использовать объявления private inheritance и using, если вы скорее не записываете функции-оболочки.


STL/Boost дают боль для получения из их контейнеров и расширять их.

Это потому, что вы не должны получать от них. Правильный способ - использовать композицию, такую ​​как фрагмент кода, представленный выше.

Ответ 4

STL и Boost являются объектно-ориентированными, как вы можете получить.

  • Во всех теоретических целях функция-член и свободная функция, перегруженная по первому аргументу, - одно и то же. Они действуют очень точно на практике, в том числе и для наследования, поэтому на С++ вы должны действительно рассматривать свободные функции, принимающие (возможно, const) ссылку в качестве первых аргументов как методы их первого аргумента.

    Преимущество бесплатных функций заключается в том, что они могут быть определены для существующего класса, что позволяет вам добавить интерфейс к существующему классу. Именно поэтому STL и особенно boost используют их так много. Главное преимущество функций-членов - они могут быть виртуальными (но виртуальные методы должны быть приватными в любом случае!)

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

Ответ 5

Ты идешь не так. Если вы хотите запрограммировать в Java, то программа на Java. Если вы программируете на С++, тогда программируйте как программисты на С++. Всегда плавайте с течением, никогда против него.

Ответ 6

Почему бы не использовать граф вместо контейнеров STL и прикрепить то, что вам нужно на узлах или краях. Они могут имитировать любые контейнеры STL (я не прав?). Вы можете легко перебирать узлы или ребра (DFS, BFS) и по тому, как вы можете делать то, что вам нравится, с данными, прикрепленными к узлам и краям. Легкое сочетание алгоритма и итератора, не так ли?

Ответ 7

Что сказал Дилавар, на самом деле является решением для всех ваших потребностей в контейнере.

Используйте Boost:: graph или аналогичную реализацию. Вы можете использовать его [это то, что я делаю] как систему управления объектами.

Что касается критики STL, это просто вопрос вкуса, а не технические возражения. Они существуют, но не на этом уровне.

Ответ 8

Придя немного опаздывать на эту вечеринку И я знаю, что OP специально просит не "понтификатировать", как они уже знают о STL, однако...

Существует старый Dr. Dobbs с Алексом Степановым, пионером в разработке общих программ и основным спонсором STL. Очень поучительно несколько способов, особенно для решения вопроса о том, почему в STL не используются более стандартные методы OO. Один абзац выделяется:

Даже сейчас наследование С++ не очень полезно для общего программирования. Давайте обсудим, почему. Многие люди пытались использовать наследование для реализации структур данных и классов контейнеров. Как мы знаем сейчас, было мало успешных попыток. Наследование С++, а связанный с ним стиль программирования резко ограничен. Невозможно реализовать дизайн, который включает в себя тривиальную вещь, как использование равенства. Если вы начинаете с базового класса X в корне вашей иерархии и определяете оператор виртуального равенства в этом классе, который принимает аргумент типа X, то выведите класс Y из класса X. Каков интерфейс равенства? Он имеет равенство, которое сравнивает Y с X. Используя животных в качестве примера (люди ОО любят животных), определите млекопитающих и выведите жирафа у млекопитающих. Затем определите член-функцию-член, где животные согласуются с животными и возвращают животное. Затем вы получаете жирафа от животного и, конечно же, у него есть помощник по функциям, где жираф соединяется с животным и возвращает животное. Это определенно не то, что вы хотите. Хотя спаривание может быть не очень важно для программистов на C++, равенство есть. Я не знаю ни одного алгоритма, где не используется какое-либо равенство.

Для тех, кто предпочитает ответ Java на эту же загадку, Джош Блох прилагает все усилия, чтобы сделать те же самые пункты в Эффективной Java, Пункт 8: Послушать общий контакт при переопределении.

Это хорошая глава, с хорошим примером о попытке сохранить равный контракт, в то же время расширяя простой класс Point и добавленный цвет: класс ColorPoint. Он продолжает демонстрировать, что существует фундаментальное ограничение ООП: нет возможности расширить экземпляр класса и добавить компонент значения при сохранении равного контракта.

Конечно, высказывание Блоха более кратко изложено, но они оба (правильно) делают одни и те же выводы. Основное отличие состоит в том, что Java является (является) языком "чистого OO" - все должно находиться в классе, даже такие вещи, как алгоритмы, которые не являются естественными объектами.

И я думаю, что Блох может быть чувствительным к этой проблеме, потому что он видел, что он не впечатляет в библиотеке Java: Stack, наследующий от Vector, является одним из примеров заметной проблемы проектирования в Java.

Чуть позже в интервью Степанов продолжает:

Я участвовал в нескольких дискуссиях на раннем этапе в Bell Labs о разработке шаблонов и довольно жестоко спорил с Bjarne о том, что он должен сделать шаблоны С++ максимально приближенными к дженерикам Ada. Я думаю, что я так сильно рассуждал, что он решил против этого. Я осознал важность наличия функций шаблона на С++, а не только классов шаблонов, как полагали некоторые люди. Я думал, однако, что функции шаблонов должны работать как генераторы Ada, то есть они должны быть явно созданы. Бьярне не слушал меня, и он разработал механизм функций шаблона, где шаблоны создаются неявно с использованием механизма перегрузки. Эта особая техника стала решающей для моей работы, потому что я обнаружил, что это позволило мне сделать много вещей, которые не были возможны в Аде. Я рассматриваю этот конкретный проект Бьярне как замечательный труд, и я очень рад, что он не последовал моему совету.