NodeRef
説明
NodeRefクラスは、ツリー内のノードへの「安全な」ポインターをカプセル化します。多くの場合、SDTまたはODTのクラスメンバーとして使用されます。基本的に「安全な」TreeNode*です。TreeNode*の代わりにNodeRefを直接使用する主なメリットは、指しているものが削除された場合に、そのものへの参照がすぐにNULLになり、無効なメモリへのポインターが残らないことが保証されることです。それでは、TreeNode*の代わりにNodeRefを使用すべきなのはどんなときでしょうか。参照しているものがクラスに知らされずに削除される可能性がある場合も、必ず、TreeNode*の代わりにNodeRefを使用する必要があります。逆参照時は何らかのチェックを行う必要があるため、NodeRefの使用に関連したオーバーヘッドが発生しますが、参照しているものが削除される可能性がある場合は、とにかく何らかのチェックを行う必要があります。また、NodeRefにそれらのチェックをカプセル化させることもできます。これにより、頭痛の種が取り除かれます。
TreeNode*の代わりにNodeRefを使用する例については、次のコードを参照してください。
class MySDT : public SimpleDataType { public: TreeNode* someNode; ... };
代わりにNodeRefを使用するには、TreeNode*をNodeRefで置き換えるだけです。
class MySDT : public SimpleDataType { public: NodeRef someNode; ... };
ほとんどの場合、TreeNode*と全く同じ方法でsomeNodeを使用することができます。ただし、c++コンパイラーが、NodeRefを他の何かにキャストする方法がわからないとか、関数呼び出しのパラメータが曖昧であるといったエラーを表示する場合があります。そのような場合は、NodeRef::get()メソッドを使用してTreeNode*を明示的に取得できます。
someNode.get()
ObjRef
ObjRefクラスは、NodeRefクラスと同様ですが、代わりに、「安全な」ポインターをSimpleDataType/ObjectDataTypeにカプセル化します。たとえば、ノードへのポインターを使用する代わりに、TaskExecuterへの安全なポインターが必要な場合は、ObjRefを使用してこれを実現できます。以下のコードを例にとりましょう。
class MySDT : public SimpleDataType { public: TaskExecuter* someTE; ... };
以下のコードを使用することにより、代わりに安全なポインターを使用できます。
class MySDT : public SimpleDataType { public: ObjRef<TaskExecuter> someTE; ... };
NodeRefと同じく、追加されたら、基本的にObjRefをポインターそのものと同様に使用できます。ObjRefには、NodeRefと同じメリットがあります。すなわち、オブジェクトが削除されると、それへの参照が自動的にNULLになります。