Re: Doubly Linked Objects
Here is an alternative using references that copies the passed in
child (but not the parent):
#include <iostream>
#include <exception>
class Node {
protected:
Node* parent;
Node* child;
std::string name;
private:
void init() {
parent = 0;
child = 0;
name = "";
}
public:
Node() {
init();
}
Node(const std::string name) {
init();
this->setName(name);
}
Node(const Node& node) {
init();
set(node);
}
virtual ~Node() {
if (hasChild()) {
delete child;
}
}
Node& operator=(const Node& node) {
set(node);
return *this;
}
void set(const Node &node) {
setName(node.getName());
if (node.hasChild()) {
Node* newChild = new Node(node.getChild());
setChild(*newChild);
}
}
void setName(const std::string& name) {
this->name = name;
}
std::string getName() const {
return name;
}
bool hasParent() const {
return parent != 0;
}
Node& getParent() const {
if (!hasParent()) {
throw std::exception("Node has no parent.");
}
return *parent;
}
void setParent(Node& node) { // Q: I take it that the dereference
stops me using const Node& node here?
parent = &node;
}
bool hasChild() const {
return child != 0;
}
Node& getChild() const {
if (!hasChild()) {
throw std::exception("Node has no child.");
}
return *child;
}
/** Create a copy of the supplied node.
* Deletes the existing node.
* @return A Reference to the child. */
Node& setChild(const Node& node) {
if (child != 0) {
delete child;
}
child = new Node(node);
child->setParent(*this);
return *child;
}
bool hasDescendant(const int& n) {
if (n==0) {
return true;
} else if (!hasChild()) {
return false;
} else {
return getChild().hasDescendant(n-1);
}
}
// Using boost::shared_ptr<Node> would not work here because n=0 can
not return boost::shared_ptr<Node>(this);
Node& getDescendant(const int& n) {
if (n==0) {
return *this;
} else {
return getChild().getDescendant(n-1);
}
}
void display(std::ostream& out) const {
out << "Node@" << this << "(name = " << getName().c_str() << ")";
if (hasChild()) {
out << std::endl << "|" << std::endl;
getChild().display(out);
}
}
};
std::ostream& operator<<(std::ostream& out,const Node& node) {
node.display(out);
return out;
}
void test() {
Node a("A");
Node b("B");
Node& addedB = a.setChild(b); // Q: Is there anyway to avoid having
to create a new reference to the added child?
Node c("C");
Node& addedC = addedB.setChild(c);
std::cout << a << std::endl << std::endl;
Node d(a);
std::cout << d << std::endl << std::endl;
std::cout << d.getDescendant(2) << std::endl << std::endl;
}
int main(int argc, char* argv[]) {
test();
std::cout << "Finished" << std::endl;
return 0;
}
/* Output:
Node@0012FE54(name = A)
|
Node@003662F0(name = B)
|
Node@00366358(name = C)
Node@0012FDA0(name = A)
|
Node@00366738(name = B)
|
Node@00366808(name = C)
Node@00366808(name = C)
Finished
*/
This seems much safer, but has the down side that we have to redeclare
the added child using a new reference variable - so we can chain
things together. Any comments/
Ta.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]