CArray <int,int =“”>和CArray <int,int&=“”>?</int,> </int,>之间有什么区别?

时间:2010-04-22 17:45:03

标签: c++ templates mfc

同样适用于CMap,CList以及使用模板的所有内容(我猜)。

我觉得有点难以理解何时使用哪个。确实,对于类等,<class, class&>表单通常是您想要的,但对于intfloat等基本类型,首选哪种形式?

2 个答案:

答案 0 :(得分:5)

我想说如果你真的不需要其他东西,只需使用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)

如果您在Typeconst Type&之间做出选择,那么唯一受影响的是要复制多少次和哪些数据。当值通过引用传递时,实际上只传递指向它的指针。这对于对象(复制构造函数的附加调用)非常重要,但对于简单类型并不重要。当然你可以尝试通过强制复制charshort小于相应的指针(32/64位,取决于平台)来保存几个字节,但我不认为这真的值得额外烦恼。正如我之前所说,我认为使用默认CArray<Type>是一种好方法,除非你真的有理由改变它。

答案 1 :(得分:2)

我经常遇到同样的问题,目前我正在努力解决一个我认为与这种差异有关的奇怪错误。我不确定我是否完全理解发生了什么,但请考虑这个操作:

a.Add(a[0]);

如果a被声明为CArray<int, int&>,那么当a太小而无法处理添加并且必须增长时,会出现这种情况。调用SetAtGrow()并生成数组的放大副本。不幸的是,现在对[0]的引用是对无效内存的引用,因为数组已经移动了。

如果a被声明为CArray<int, int>,那么[0]的副本将传递给Add函数,并且没有问题。

同样,我仍然试图解决这个问题(这就是为什么我最终找到了这个讨论),但如果您在执行操作时引用自己的CArray,那么使用引用似乎存在一个微妙的问题增加它的大小。您无法信任该引用,因此CArray<int, int>似乎更受欢迎。