私はC++を使用していますが、参照カウントされたオブジェクトを使って大きなグラフを表現しています。ような何か:C++の低速再帰デストラクタコール
// Public class
class Pointer{
public:
// Constructors
Pointer(...){ node = ...; node->counter++;}
// Copy constructor
Pointer(Pointer& const other){ node = other.node; node->counter++;}
// Destructor
~Point(){ if(--node->counter==0) delete node;}
// Other methods
...
Node* node;
};
// Node base class
class Node{
// Constructor
Node():counter(0){}
// Destructor
virtual ~Node(){}
// public:
unsigned long counter;
};
// Node derived class
class NodeDerived : public Node{
// Constructors and other methods
...
// Destructor
virtual ~NodeDerived(){ ... }
// Children
Pointer children[2];
};
多型クラスのノードへのポインタを含むパブリッククラスPointer
とされています。 Nodeから派生したクラスには、新しいPointer
インスタンスが含まれます。いくつかのPointer
インスタンスが同じNode
インスタンスを指している可能性があることに注意してください。
私はこのクラスを使用して、数百万のインスタンスを持つ非常に大きなグラフを構築しています。これはうまくいきます。この問題は、グラフを削除するときに発生します。デフォルトのデストラクタ実装では、スタック・オーバーフローが発生します。これは、ルート・ノードのデストラクタでは、子のデストラクタがコールされ、子のデストラクタでは、子の子のデストラクタがコールされるなどです。
上記のNodeDerived
クラスのデストラクタを実装することで、スタックを使用して再帰呼び出しを避けることでこれを解決しました。これは動作しますが、まだ非常に遅いですし、私はこれをスピードアップする方法を探しています。どうやらメモリリークを引き起こすことなくデストラクタ宣言を避けることが可能ですか?virtual
?
確かに、繰り返しによって再帰を置き換えますが、別のデータ構造が必要です。これは探検の良い方向のように聞こえる。 –
@Jason。さて、私は別のストレージスキームについて考えていました。おそらく 'Pointer'クラスにある種のハッシュインデックスが含まれていましたが、私はすでに多くのストレージスキームを試しました。これはこれまでのところ、 。 – Joel
'std :: set'は、オブジェクトを見つけるのに一定の時間を要しないのでオプションではありません。私たちのプログラムはまだC++ 0Xを使用できないので、' std :: unordered_set'もありません。私が 'std :: shared_ptr'の速度とオーバーヘッドを心配する必要はないと私の場合は真実ではありません。私はSTLに入ってから試してみませんでしたが、Boostバージョン(2年ほど前)を使用したときには遅すぎてメモリを使いすぎました。実際、Boost 'shared_ptr 'での私の経験は、私がこのクラスを最初に書くように導いてくれました。 – Joel