В чем разница между CArray<int, int> и CArray<int, int &>?
То же самое для CMap, CList и почти всего, что использует шаблоны (наверное).
Мне немного трудно понять, когда использовать какой. Это правда, что для классов и тому подобное, <class, class&>
Форма, как правило, то, что вы хотите, но для основных типов, таких как int
, float
и т. д., какая форма является предпочтительной?
2 ответа
Я бы сказал, что если вам не нужно что-то еще, просто используйте 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>
это хороший способ, если у вас нет причин менять его.
У меня часто возникал один и тот же вопрос, и в настоящее время я пытаюсь решить странную ошибку, которая, по моему мнению, связана с этой разницей. Я не уверен, что я полностью понимаю, что происходит, но рассмотрим эту операцию:
a.Add(a[0]);
Если объявлен как CArray<int, int&>
, то есть грубый случай, когда a слишком мало, чтобы справиться с сложением и должно быть выращено. SetAtGrow() вызывается и создает увеличенную копию массива. К сожалению, ссылка на [0] теперь является ссылкой на недопустимую память, так как массив переместился.
Если объявлен как CArray<int, int>
затем копия [0] передается в функцию Add, и проблем не возникает.
Опять же, я все еще пытаюсь выяснить это (именно поэтому я и нашел это обсуждение), но, похоже, есть небольшая проблема с использованием ссылок, если вы когда-нибудь будете ссылаться на свой собственный CArray при выполнении операции, которая увеличит его размер, Вы не можете доверять ссылке так CArray<int, int>
кажется предпочтительным.