Mi-ar schimba pur și simplu copacul în sine, ar fi mai ușor să se ocupe de ea, atunci:
struct Node
{
Node(data_type data): mLeft(), mRight(), mData(data) {}
Node(const Node& rhs): mLeft(), mRight(), mData(rhs.mData)
{
if (rhs.mLeft.get()) mLeft.reset(new Node(*rhs.mLeft));
if (rhs.right.get()) mRight.reset(new Node(*rhs.mRight));
}
Node& operator=(Node rhs)
{
this->swap(rhs);
return *this;
}
~Node() { }
void swap(Node& rhs)
{
using std::swap;
swap(mLeft, rhs.mLeft);
swap(mRight, rhs.mRight);
swap(mData, rhs.mData);
}
Node* left() const { return mLeft.get(); }
void left(std::auto_ptr<Node> node) { mLeft= node; }
Node* right() const { return mRight.get(); }
void right(std::auto_ptr<Node> node) { mRight = node; }
data_type& data() { return mData; }
const data_type& data() const { return mData; }
private:
std::auto_ptr<Node> mLeft;
std::auto_ptr<Node> mRight;
data_type mData;
};
Fiind Orientate-obiect, fiecare nod este acum responsabil pentru memoria se ocupă. De asemenea, folosind std::auto_ptrîn interfața arată clar că este nevoie de proprietate.
Rețineți că acesta a fost adaptat pentru deep-copiere, orice altă abordare care necesită boost::shared_ptrsau echivalent. Și da , std::auto_ptrte lasă face cu copierea de unul singur, nici o magie acolo.
Acest design este mult mai curat decât cu ajutorul unui simplu C-structcu toată lumea fiind capabil de a manipula resursele. Încă mai avea acces deplin la datele care stau la baza prin intermediul accessor ... dar ei avea grijă să nu invoce un comportament nedefinit ...
Desigur, puteți totuși crash jos:
Node& node = ...
delete node.left(); // haha
Dar dacă C ++ poate proteja împotriva probleme neintenționate, lasă ușa deschisă la codul rău.