В чем разница между CArray <int, int> и CArray <int, int &>? - PullRequest
3 голосов
/ 22 апреля 2010

То же самое для CMap, CList и почти всего, что использует шаблоны (наверное).

Мне немного сложно понять, когда использовать какой. Это правда, что для классов и тому подобного форма <class, class&> обычно является тем, что вам нужно, но для базовых типов, таких как int, float и т. Д., Какая форма предпочтительнее?

Ответы [ 2 ]

5 голосов
/ 22 апреля 2010

Я бы сказал, что если вам не нужно что-то еще, просто используйте CArray<Type>, и ARG_TYPE будет по умолчанию const TYPE&. На самом деле использование Type& в качестве ARG_TYPE не очень хорошая идея. Это теоретически позволяет CArray изменить объект / значение, которое вы передали в соответствующий метод. Конечно, CArray ничего подобного не делает, но лучше быть в безопасности.

Если вы посмотрите на исходный код, доступный в MS VC, вы увидите, что ARG_TYPE используется в нескольких методах как тип для аргумента, который содержит новое значение для некоторых элементов массива, таких как

void SetAt(INT_PTR nIndex, ARG_TYPE newElement)
INT_PTR Add(ARG_TYPE newElement)
void SetAt(INT_PTR nIndex, ARG_TYPE newElement)
void InsertAt(INT_PTR nIndex, ARG_TYPE newElement, INT_PTR nCount = 1)

Если вы делаете выбор между Type и const Type&, то единственное, что влияет на это, - это сколько раз и какие данные будут скопированы. Когда значение передается по ссылке, фактически передается только указатель на него. Это действительно важно для объектов (дополнительный вызов конструктора копирования), но не имеет значения для простых типов. Конечно, вы можете попытаться сэкономить несколько байтов, принудительно копируя char или short, который меньше соответствующего указателя (32/64 бит в зависимости от платформы), но я не думаю, что это действительно стоит дополнительных проблем. Как я уже говорил, я думаю, что использование по умолчанию CArray<Type> - это хороший способ, если у вас действительно нет причин для его изменения.

2 голосов
/ 30 января 2011

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

a.Add(a[0]);

Если a объявлено как CArray<int, int&>, то существует грубый случай, когда a слишком мало для обработки сложения и должно быть увеличено. SetAtGrow () вызывается и создает увеличенную копию массива. К сожалению, ссылка на [0] теперь является ссылкой на недопустимую память, так как массив переместился.

Если a объявлено как CArray<int, int>, то копия [0] передается в функцию Add, и проблема не возникает.

Опять же, я все еще пытаюсь выяснить это (именно поэтому я и нашел это обсуждение), но, похоже, есть небольшая проблема с использованием ссылок, если вы когда-нибудь будете ссылаться на свой собственный CArray при выполнении операции, которая увеличить его размер. Вы не можете доверять ссылке, поэтому CArray<int, int> кажется предпочтительным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...