我在代码中发现了类似这样的内容:
void foo(IList<int>^ const & list ) { ... }
^ const&
是什么意思?我查看了C ++ / CLI规范,但没有发现有关进行常量跟踪引用的评论,也没有发现^&
组合。
这合法吗?
这是对跟踪句柄恒定的引用。
它允许您按引用而不是按值传递句柄。据推测,作者认为它比复制手柄更有效。
[If作者的意图是使该手柄保持不变,他应该使用其中的任何一种
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;
}
此代码可能是由使用通用C ++惯用法编写C ++ / CLI的C ++程序员编写的。这是完全错误的,只有将句柄存储在堆栈中时,才可以将引用传递给跟踪句柄。如果传递的List <>引用存储在堆上的对象的字段中,则它无法工作,垃圾回收器可以移动它并使指针无效。编译器将捕获它并生成错误。 ^已经是参考,不需要其他参考。
没有参考,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);
}
};