Вопрос

Прямо сейчас я использую std::pair для представления 2d-точки в С++.Однако меня раздражает необходимость писать

typedef std::pair<double, double> Point;

Point difference = Point(p2.first - p1.first,
                         p2.second - p1.second);

вместо возможности перегружать оператор+ и оператор-.

Итак, мой вопрос: нужно ли мне создавать класс Point?

  • Публично вывести из std::pair и добавить свои собственные функции-члены?Это хорошо, потому что весь мой код может остаться прежним.Я не собираюсь делать ничего подобного std::pair<double, double>* p = new Point; поэтому мне не нужно беспокоиться о таких вещах, как виртуальные деструкторы.
  • Создайте свой собственный класс Point, что раздражает, поскольку я дублирую функциональность std::pair, однако я «делаю это в чистом виде».
  • Создайте шаблонные специализации оператора+ и оператора- для std::pair, которые, честно говоря, я не помню, находятся ли они в исходных файлах или файлах заголовков.

Я думаю, это подлежит обсуждению, мне бы очень хотелось сделать № 1, но я не знаю, плохая ли это идея, поскольку я слышал, что наследование от STL запрещено.

Это было полезно?

Решение

Вы можете создать свой собственный класс Point, но использовать для внутреннего хранения данных std::pair.Это предотвращает проблему наследования от STL, но по-прежнему использует функциональность std::pair.

Другие советы

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

Я бы предпочел создать собственный класс Point и использовать либо частное наследование, либо композицию, если вы хотите использовать функциональность std::pair.Проблема с typedef (я уверен, вы знаете) заключается в том, что любая написанная вами функция, принимающая Point, также будет использоваться чем-либо, представленным как std::pair<double, double>, что может быть недопустимым.

Имея это в виду, существует другой вариант: просто создать несколько бесплатных функций компоновщика, таких как

Point addPoints(const Point& p1, const Point& p2);
Point diffPoints(const Point& p1, const Point& p2);

(имена функций могли бы быть лучше).

Еще один вариант может заключаться в том, чтобы сделать вас собственным классом Point и сделать так, чтобы ваш класс «владел» std::pair, который представляет координаты точки.

Во многих случаях отношение «HAS A» (композиция) предпочтительнее отношения «IS A» (наследование).

Я думаю, что в «Лучших практиках» предлагается создать собственный класс Point.Таким образом, вы сможете значительно упростить работу с 3D в будущем.

Частное наследование, иначе говоря, наследование реализации, — ваш друг.

Это логически следует:Point НЕ является std::pair, вы не хотите иметь публичное преобразование с повышением из Point в std::pair, но вы хотите использовать внутренние компоненты std::pair.

Другая возможность связана с отношением «имеет» или композицией:каждая точка имеет частную std::pair, которую она использует внутри себя.

На самом деле, между композицией и частным наследованием нет большой разницы, за исключением того, что в последнем вы можете принудительно выполнить приведение к std::pair в функции-члене Point.

Создайте свой собственный класс Point.Это позволит вам делать с ним любые вещи в будущем.В частности, я уже решал подобные проблемы раньше и нашел полезным определить собственную структуру Point и создать класс Point, который наследуется от нее.

Полное раскрытие:Мне не очень нравится STL.

Не наследуйте публично от std::pair, потому что у std::pair есть оператор <, но у вашего Point его не должно быть.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top