2009-04-30 3 views
6

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

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

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

вместо того, чтобы быть в состоянии перегрузки оператора + и operator-.

Итак, мой вопрос, чтобы сделать свой класс Point, я должен

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

Я предполагаю, что это дебаты, я бы очень хотел сделать # 1, но я не знаю, плохо ли это, так как я слышал, что наследование от STL - это не-нет.

+3

FYI - причина, наследующая от STL, - это не-нет, это отсутствие виртуального деструктора. Итак, если вы удалили свой собственный класс с помощью указателя на базовый тип STL, ваш деструктор не будет вызван. – JohnMcG

+0

Я сказал, что не буду этого делать в вопросе. – rlbond

+0

Не думал, что вы это сделаете; просто подумал, что было бы полезно указать причину. – JohnMcG

ответ

14

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

+1

+1. Если вам случится читать Code Complete, он предлагает эту точную практику: если [класс Point] * является * a [std :: pair], наследуйте. В противном случае [std :: pair] следует сохранить как частный член, а [Point] должен определить собственный интерфейс. «point.first» не имеет смысла; пункт.x. – ojrac

+0

Скорее всего, я получил эту идею. Эта книга скалы! –

+0

Я понимаю, почему наследование от 'stl :: pair' не является хорошим; но зачем вообще использовать 'stl :: pair'? Какие функции 'stl :: pair' относятся к' Point'? Может быть, мне не хватает чего-то очевидного, но заказы, 'swap',' get', разные конструкторы кажутся неактуальными для «Point». – max

1

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

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

1

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

+0

абсолютно нет необходимости в 3d. Это для игры. 2d игра. – rlbond

+0

2 размеров должно быть достаточно для всех !!! Извини за это –

1

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

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

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

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

0

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

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

2

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

2

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

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

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

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

0

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

Смежные вопросы