Ik zou gewoon de boom zelf te veranderen, zou het gemakkelijker zijn om te gaan dan:
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;
};
Door Object-Oriented, elk knooppunt is nu verantwoordelijk voor het geheugen wordt omgegaan. Ook het gebruik van std::auto_ptrin de interface maakt duidelijk dat het duurt ownership.
Merk op dat het is op maat gemaakt voor deep-kopiëren, een andere aanpak vereisen boost::shared_ptrof gelijkwaardig. En ja std::auto_ptrlaat je omgaan met het kopiëren door jezelf, geen magische daar.
Dit ontwerp is veel schoner dan het gebruik van een vlakte C-structmet iedereen de mogelijkheid om de middelen te manipuleren. Je hebt nog steeds volledige toegang tot de onderliggende gegevens via de accessor ... maar ze zorgen voor onbepaald gedrag geen beroep te doen ...
Natuurlijk kunt u nog steeds crashen naar beneden:
Node& node = ...
delete node.left(); // haha
Maar als C ++ kan beschermen tegen onbedoelde kwesties, laat de deur open voor het kwade code.