この文書の現在のバージョンと選択したバージョンの差分を表示します。
次のリビジョン | 前のリビジョン | ||
cli:interior_ptr [2009/01/31 11:05] admin 作成 |
cli:interior_ptr [2013/12/23 09:08] (現在) |
||
---|---|---|---|
ライン 1: | ライン 1: | ||
- | vvsdvsdvsd | + | {{indexmenu_n>10}} |
+ | ====== interior_ptr ====== | ||
+ | |||
+ | |||
+ | interior_ptrはマネージヒープ上にあるvalue typeや基本型を指すためのポインタです。 | ||
+ | |||
+ | 以下のコードを考えます。 | ||
+ | <code cpp> | ||
+ | ref class R | ||
+ | { | ||
+ | public: | ||
+ | Object o; | ||
+ | int i; | ||
+ | }; | ||
+ | void set100(int* i) | ||
+ | { | ||
+ | *i = 100; | ||
+ | } | ||
+ | int main() | ||
+ | { | ||
+ | R^ r = gcnew R; | ||
+ | set100(&r->i); | ||
+ | } | ||
+ | </code> | ||
+ | このコードはset100()でエラーになります。マネージヒープ上にあるものはポインタで受け取ることはできません。マネージヒープ上のデータはいつ場所が変わるかわからないため、純粋なアドレスを保持するポインタではまずいのです。 | ||
+ | |||
+ | |||
+ | そこで以下のようにして見ます。 | ||
+ | <code cpp> | ||
+ | ref class R | ||
+ | { | ||
+ | public: | ||
+ | Object o; | ||
+ | int i; | ||
+ | }; | ||
+ | void set100(int^ i) | ||
+ | { | ||
+ | i = 100; | ||
+ | } | ||
+ | int main() | ||
+ | { | ||
+ | R^ r = gcnew R; | ||
+ | set100(r->i); | ||
+ | } | ||
+ | </code> | ||
+ | こうするとset100()のところではr->iはボックス化されてしまい、100がセットされるのは、新しく作られたintインスタンスに対してです。このインスタンスはいずれ捨てられてしまいます。 | ||
+ | |||
+ | そこでinterior_ptrを用いて以下のように書きます。 | ||
+ | <code cpp> | ||
+ | ref class R | ||
+ | { | ||
+ | public: | ||
+ | Object o; | ||
+ | int i; | ||
+ | }; | ||
+ | void set100(interior_ptr<int> i) | ||
+ | { | ||
+ | *i = 100; | ||
+ | } | ||
+ | int main() | ||
+ | { | ||
+ | R^ r = gcnew R; | ||
+ | set100(&r->i); | ||
+ | } | ||
+ | </code> | ||
+ | これでr->iを変更することができます。また普通のint*をset100()に渡すこともできます。 | ||
+ | |||
+ | また、トラッキング参照を用いて以下のように書くこともできます。 | ||
+ | <code cpp> | ||
+ | ref class R | ||
+ | { | ||
+ | public: | ||
+ | Object o; | ||
+ | int i; | ||
+ | }; | ||
+ | void set100(int% i) | ||
+ | { | ||
+ | i = 100; | ||
+ | } | ||
+ | int main() | ||
+ | { | ||
+ | R^ r = gcnew R; | ||
+ | set100(r->i); | ||
+ | } | ||
+ | </code> | ||
+ | トラッキング参照も、普通のintを受け取ることができます。 |