/* definitions are residing in this header since that's how templates get * expanded, we could have a separate node.cpp is compiler supports export keyword, * instantiations of code are compiled along with the translation units that spawn them */ #ifndef _MYNODE_H_ #define _MYNODE_H_ #include template class Node { public: Node(); Node(const Node &); Node& operator=(const Node &); Node(T); Node(T &); ~Node(); T getVal(void) const; void setVal(T); void setLeft(const Node *); void setRight(const Node *); Node& getLeft(void) const; Node& getRight(void) const; private: T v; Node *left; Node *right; protected: }; template Node::Node() : v(0), left(NULL), right(NULL) { } template Node::Node(const Node& n) { this->v = n.v; this->left = n.left; this->right = n.right; } template Node& Node::operator=(const Node &rhs) { /* don't assign same object */ if (this == &rhs) /* rhs is a rvalue, hence take addr of it */ return *this; this->v = rhs.v; /* these also will assign subtrees, use it wisely? */ this->left = rhs.left; this->right = rhs.right; return *this; } template Node::Node(T n) : left(NULL), right(NULL) { this->v = n; } template Node::Node(T& n) : left(NULL), right(NULL) { this->v = n; } template Node::~Node() { } template T Node::getVal(void) const { return (this->v); } template void Node::setVal(T v) { this->v = v; } template void Node::setLeft(const Node *n) { this->left = const_cast *>(n); } template void Node::setRight(const Node *n) { this->right = const_cast *>(n); } template Node& Node::getLeft(void) const { return *(this->left); } template Node& Node::getRight(void) const { return *(this->right); } #endif