2010-01-07 67 views
1

这将是一个非常愚蠢的问题,但可以在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); 
} 

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

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

这++可以使用C中的引用,不幸的是我不知道怎么投一个数组^数组^ &我也不能使用数组^%作为成员:

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

这是不可能的,因为引用是按值存储的:也就是说,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--它仍然指的是大小为10的数组。

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

+0

但我传递的参考是跟踪/参考。比如,我应该在构造函数中调整数组的大小,而main中的数组也会被修改。 – Anzurio 2010-01-07 04:07:48

+0

但是CLR不支持by-ref成员。 (我应该更新我的答案来说这个,而不是“引用是按值传递的。”)m_data是一个普通的旧引用,而不是对引用的引用:对引用的引用只与传入它的行为有关,脱离构造函数方法。 – itowlson 2010-01-07 04:14:22

+0

我已经更新了答案,希望能够更清楚地了解参考成为“独立副本”的时间。对不起,原来是误导。 – itowlson 2010-01-07 04:17:56