実区間 (a, b) を帰納的に多くの小さな区間に分割し、中点を選択することを目的とする二分木クラスがあるとします。注意: 私が実際に書いているクラスは平面上の三角形を扱っていますが、考え方は同じです。
ヘッダー ファイル内のクラスは次のようになります。
class Tree
{
public:
Tree(double &a, double &b, int depth);
~Tree();
Tree getCopy() const;
private:
Tree(double *a, double *b, int depth, int maxDepth);
double *a, *b;
int depth, maxDepth;
Tree *leftChild, *rightChild;
};
ツリーは、実際の double ではなく、double の a と b へのポインターを格納することに注意してください。その理由は、メモリ (および速度?) を節約するためであり、a と b が多くの子ツリーによって共有されることに注意してください (double は非常に「軽い」ことはわかっていますが、実際のクラスでは「より重い」ものがあります。 」)。
ここにメインコンストラクターがあります:
Tree::Tree(double *a, double *b, int depth, int maxDepth) :
depth(depth), maxDepth(maxDepth)
{
if (depth == maxDepth)
{
this->a = new double(*a);
this->b = new double(*b);
}
else
{
this->a = a;
this->b = b;
}
if (depth == 0)
{
leftChild = 0;
rightChild = 0;
}
else
{
double * midpoint = new double((*a+*b)/2);
leftChild = new Tree(a, midpoint, depth - 1, maxDepth);
rightChild = new Tree(midpoint, b, depth - 1, maxDepth);
}
}
そしてデストラクタ:
Tree::~Tree()
{
if (depth == 0)
{
delete b;
}
else
{
delete leftChild;
delete rightChild;
}
if (depth == maxDepth)
{
delete a;
}
}
これらの機能が両方とも正しいことを願っています。コンストラクターがプライベートであることに注意してください。これは、再帰的に呼び出されるものです。パブリック コンストラクターは次のとおりです。
Tree::Tree(double &a, double &b, int depth)
{
*this = *(new Tree(&a, &b, depth, depth));
}
これは奇妙に見えますが、これを行うことでメモリリークが発生するのではないかと心配していますか? しかし一方で、私が書いた場合:
*this = Tree(&a, &b, depth, depth);
それは失敗しませんか?等価関数を考慮して、失敗する可能性があると思う理由を説明してみましょう
{
Tree T(&a, &b, depth, depth);
*this = T;
}
この関数が終了するとすぐに、オブジェクト T が破棄されるため、子が削除されるなどと考えています。
同じ懸念が copy 関数にも当てはまります。
Tree Tree::getCopy() const
{
return Tree(a, b, depth, depth);
}
問題は次のとおりです。これらの関数を記述する正しい方法は何ですか? また、このクラスの書き方について一般的な意見を聞くこともできます。前もって感謝します!