CArray<int, int>和CArray<int, int&>有什么区别?

3

对于使用模板的所有内容,如CMap、CList等,都是一样的(我猜测)。

我发现有点难理解什么时候使用哪个。确实,对于类和类似的东西,<class, class&>形式通常是你想要的,但对于像intfloat等基本类型,哪种形式更受欢迎呢?

2个回答

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& 之间,那么唯一影响的是需要复制多少次和哪些数据。当值通过引用传递时,实际上只传递了指向它的指针。这对于对象来说非常重要(需要额外调用复制构造函数),但对于简单类型并不重要。当然,你可以尝试通过强制复制比相应指针(32/64位取决于平台)更小的 charshort 来节省一些字节,但我认为这不值得额外的麻烦。正如我之前所说,除非你真的有理由改变它,否则使用默认的 CArray<Type> 是一个好方法。

2

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

a.Add(a[0]);

如果将a声明为CArray<int, int&>,则在a太小以处理添加并且必须增长时会出现粗略情况。 SetAtGrow()被调用并使数组扩大的副本。不幸的是,对a[0]的引用现在是对无效内存的引用,因为数组已经移动了。
如果将a声明为CArray<int, int>,则会向Add函数传递a[0]的副本,没有问题。
再次强调,我仍在努力弄清楚这一点(这就是我最终找到这个讨论的原因),但使用引用似乎存在微妙的问题,如果您在执行会增加其大小的操作时引用自己的CArray,则不能信任该引用,因此CArray<int, int>似乎更可取。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接