如何在C ++ / CLI中模拟成员引用跟踪变量?

时间:2010-01-07 03:23:55

标签: .net visual-c++ c++-cli

这将是一个非常愚蠢的问题,但是可以在C ++ / CLI中执行以下操作吗?

// C++/CLI
public ref class Managed
{
    public:
        array<double>^ m_data;
        Managed(array<double>^% data) : m_data(data)
        {
        }

        void bar(int x)
        {
            System::Array::Resize(m_data, x);
        }
};
// C#
static void Main(string[] args)
{
    double [] d = new double[10];
    Foo.Managed f = new Foo.Managed(d);
    f.bar(5);
}

这样,之后从Main调用f.bar(5),Main :: d和f.m_data是相同的“重新分配”数组?我尝试过非托管引用,指针,pin_ptr等等,但没有。有任何想法吗?如果这是不可能的,有原因吗?

使用引用跟踪运算符(%)如果我想在构造函数中调整大小,我可以这样做,这就是它让我尝试的东西。

这在使用引用的C ++中是可能的,遗憾的是我不知道如何将数组^转换为数组^&amp;也不能使用array ^%作为成员:

class Foo{
public:
    double *& m_data;
    Foo(double*& data): m_data(data)
    {
    }

    void bar(int x)
    {
        delete m_data;
        m_data = new double[x];
    }

    ~Foo(){
        delete [] m_data;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{

    double* data = new double[10];

    Foo f(data);
    std::cout << &data << "\n" << &f.m_data << "\n";
    f.bar(5);
    std::cout << &data << "\n" << &f.m_data;
    getchar();
    return 0;
}

1 个答案:

答案 0 :(得分:1)

这是不可能的,因为引用是按值存储的:也就是说,CLR不支持by-ref成员字段。 (Eric Lippert discusses why here (around the second list of bullet points).)因此虽然d通过引用传递给Managed的构造函数,但是当Managed将它存储在m_data中时,它会将Main的引用的副本带到size-10数组,并且此副本现在是独立的原来的。 bar函数将f的m_data引用(它是Main的引用的一个独立副本)传递给Array :: Resize,它修改m_data以引用一个新的size-5数组。但是因为m_data是一个独立的副本,它不会影响Main.d - 仍然引用size-10数组。

一种可能的替代策略是将数组引用封装在一个小的shim类中,并使Main create(和Foo.Managed accept)成为shim类的一个实例。然后bar可以调整垫片指向的数组的大小。因为Main.d和f.m_data仍然是对同一个垫片的引用(并因此共享对真实数组的单个引用),Main.d将看到调整大小的数组(通过垫片)。