C ++ / CLI, «постоянная» ссылка на дескриптор отслеживания - PullRequest
3 голосов
/ 10 мая 2010

Я заметил что-то подобное в коде:

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

Что это значит ^ const&? Я посмотрел в спецификации C ++ / CLI, но не нашел ни комментариев о постоянных ссылках на отслеживание, ни о комбо ^&.

Это законно?

Ответы [ 2 ]

9 голосов
/ 10 мая 2010

Этот код, вероятно, был написан программистом C ++, который использовал общий язык C ++ для написания C ++ / CLI. Это совершенно неправильно, передача ссылки на дескриптор отслеживания возможна, только если дескриптор хранится в стеке. Он не может работать, если переданная ссылка 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);
    }
};
3 голосов
/ 10 мая 2010

Это ссылка, которая является постоянной для маркера отслеживания.

Позволяет передавать дескриптор по ссылке, а не по значению. Предположительно автор считает, что это более эффективно, чем копирование дескриптора.

Если , автор хотел сделать дескриптор константным, он должен был использовать любой из

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...