我在代码中发现了类似的内容:
void foo(IList<int>^ const & list ) { ... }
这^ const&
是什么意思?我查看了C ++ / CLI规范,但没有发现关于进行常量跟踪引用的评论,也没有发现^&
组合。
这合法吗?
答案 0 :(得分:9)
这段代码可能是由C ++程序员编写的,它使用常见的C ++习惯用法编写C ++ / CLI。这是非常错误的,只有当句柄存储在堆栈上时,才能传递对跟踪句柄的引用。如果传递的List&lt;&gt;它不能工作。引用存储在堆上的对象的字段中,垃圾收集器可以移动它并使指针无效。编译器将捕获它并生成错误。 ^已经是参考,不需要额外的参考。
没有引用,const关键字也不再有意义。不是以前做过的,CLR无法强制执行。这并不重要,这个代码无法从任何其他.NET语言调用。它们不会生成指向跟踪句柄的指针。
修复它,保持这样的坏代码没什么意义:
void foo(IList<int>^ list ) { ... }
显示引用无效的代码示例:
using namespace System;
using namespace System::Collections::Generic;
ref class Test {
public:
IList<int>^ lst;
void foo(IList<int> const &list) {}
void wontcompile() {
foo(lst); // C3699
IList<int>^ okay;
foo(okay);
}
};
答案 1 :(得分:3)
这是一个对跟踪句柄不变的引用。
它允许您通过引用而不是值传递句柄。据推测,作者认为它比复制手柄更有效。
如果作者意图使句柄保持不变,他应该使用
中的任何一个Method(TestClass const ^ const & parameter)
Method(TestClass const^ parameter)
或者
Method(TestClass const^& parameter)
- 但调用者必须首先构建句柄
同
TestClass const^ constHandle = nonConstHandle
每个例子:
// test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
ref class TestClass
{
public:
void setA(int value)
{
a = value;
}
TestClass() :
a(10)
{
}
private:
int a;
};
class TakesHandle
{
public:
void methodX1(TestClass const ^ const & parameter)
{
// Un-commenting below causes compiler error
// parameter->setA(11);
}
void methodX2(TestClass const^ parameter)
{
// Un-commenting below causes compiler error
// parameter->setA(11);
}
void methodX3(TestClass const^& parameter)
{
// Un-commenting below causes compiler error
// parameter->setA(11);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
TakesHandle takes;
TestClass ^ test1 = gcnew TestClass();
// compiles
takes.methodX1(test1);
// compiles
takes.methodX2(test1);
TestClass const ^ constHandle = test1;
takes.methodX3(constHandle);
return 0;
}