2010-01-07 77 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