C ++ / CLI,对跟踪句柄的“常量”引用

时间:2010-05-10 14:50:58

标签: c++-cli

我在代码中发现了类似的内容:

void foo(IList<int>^ const & list ) { ... }

^ const&是什么意思?我查看了C ++ / CLI规范,但没有发现关于进行常量跟踪引用的评论,也没有发现^&组合。

这合法吗?

2 个答案:

答案 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;
}