2020年1月16日 星期四

C++及C++\CLI 修改指標變數的方法 (雙重指標的應用)

在原生的C++ (native C++)中,若要修改指標變數,會用雙重指標(指標的指標),
就像要修改某變數時,要將該變數的指標傳入函數一樣的道理。
下面是原生C++要修改指標變數時的方法
#include <iostream>

class UnmanagedClass
{
public:
int i;
};

void ModifyUnmanagedPointer(UnmanagedClass** p)
{
*p = new UnmanagedClass();
(*p)->i = 100;
}

void main()
{
UnmanagedClass* p;
ModifyUnmanagedPointer(&p);
std::cout << "value = " << p->i << std::endl;
system("pause");
}

其輸出為:


此道理在C++\CLI (C++的.net版本,以下簡稱CLI)中也不例外,
不過由於托管類別(managed class)都被托管,
沒辦法直接使用「^^」來做為托管指標的位址。
以下介紹兩種修改托管指標的方法:

方法一:傳托管指標的位址
在函數的宣告時,
托管指標的位址要透過interior來宣告
#include <iostream>

public ref class ManagedClass
{
public:
int i;
};

void ModifyManagedClassByOut(cli::interior_ptr<ManagedClass^> p)
{
*p = gcnew ManagedClass();
(*p)->i = 101;
}

void main()
{
ManagedClass^ p;
ModifyManagedClassByOut(&p);

std::cout << "value = " << p->i << std::endl;
system("pause");
}

輸出為:


方法二:傳托管指標的參考
在CLI中,傳托管指標的參考要用「%」運算子,
不過僅限於在函數宣告的時候,
在傳入時,要用「&」,這點與原生C++一樣!
#include <iostream>

public ref class ManagedClass
{
public:
int i;
};

void ModifyManagedClassByRef(ManagedClass^ %p)
{
p = gcnew ManagedClass();
p->i = 102;
}

void main()
{
ManagedClass^ p;
ModifyManagedClassByRef(p);

std::cout << "value = " << p->i << std::endl;
system("pause");
}

輸出為

傳托管指標的參考宣告,也可寫在一起「^%」,
意思是一樣的。

值得注意的是,上述介紹的兩種宣告方式,
在其他.NET的語言中(像是C#、VB.NET),要用ref關鍵字。
e.g.
在C#中看到的會是
void ModifyManagedClassByOut(ref ManagedClass p);

由於C#、VB.NET中的ref會先分配記憶體給該變數,
所以若是寫給其他.NET語言時,在函數中可以不分配記憶體給該變數!


參考資料:









這封郵件來自 Evernote。Evernote 是您專屬的工作空間,免費下載 Evernote

沒有留言:

張貼留言