I have this tree with different types of nodes that I need to do a deep copy on. The hierarchy looks something like this:
class AllNodes
{
//this is a purely virtual base class
};
class TreeNode : public AllNodes
{
AllNodes *rChild, *lChild;
};
class LeefNode : public AllNodes
{
int value;
};
The problem is that when I want to do a deep copy of the entire tree, I don't know what nodes will have children and what nodes will have values. I've tried this, but it wont work (for obvious reasons):
void AllNodes::deepCopy(AllNodes* &copied, AllNodes* o)
{
if(o->rChild == nullptr)
copied->rChild = nullptr;
else
{
copied->rChild = o->rChild;
deepCopy(copied->rchild, o->rChild);
}
if(o->lChild == nullptr)
copied->lChild = nullptr;
else
{
copied->lChild = o->lChild;
deepCopy(copied->lChild, o->lChild);
}
}
Does anyone have some ideas of how to accomplish this?
Create a virtual method and implement it in TreeNode and LeafNode.
class AllNodes
{
//this is a purely virtual base class
virtual AllNodes* copy() const = 0;
};
class TreeNode : public AllNodes
{
AllNodes* rChild, lChild;
virtual AllNodes* copy() const {
TreeNode *n = new TreeNode;
n->rChild = rChild->copy();
n->lChild = lChild->copy();
return n;
}
};
class LeafNode : public AllNodes
{
int value;
virtual AllNodes* copy() const {
LeafNode *n = new LeafNode;
n->value = value;
return n;
}
};
(Just a draft)
This is polymorphic behavior (creating a deep copy, based on the concrete type of the object). As such, it should be implemented in a virtual function, accross the entire nodes hierarchy.
The function to perform the deep copy is usually called clone:
class AllNodes
{
//this is a purely virtual base class
public:
virtual AllNodes* clone() = 0;
};
class TreeNode : public AllNodes
{
AllNodes *rChild, *lChild; // you skipped declaring lChild as a pointer
public:
virtual AllNodes* clone() override // recursive implementation for child nodes
{
return new TreeNode{
rChild ? rChild->clone() : nullptr,
lChild ? lChild->clone() : nullptr }; // assume existence of this
// constructor
}
};
class LeafNode : public AllNodes
{
int value;
public:
virtual AllNodes* clone() override
{
return new LeafNode{ value }; // assume existence of this constructor
}
};
Client code (deep copy of the entire tree):
AllNodes *original; // filled in elsewhere
AllNodes *deepCopy = original->clone();
Related
I have a tree structure, created from derived classes from Node. Each Node has pointer to it's parent and a virtual function Symbols(). Here is simplified example:
struct Node {
Node* parent;
virtual const SymbolTable& Symbols() { return parent->Symbols(); }
}
struct A : public Node {
}
struct B : public Node {
SymbolTable symbols;
const SymbolTable& Symbols() override { return symbols; }
}
So in this tree structure, A nodes doesn't have SymbolTable and B nodes do. All I need to do is for the Symbols() method return first SymbolTable above current node, but it seems that the overridden method in B is never getting called.
I just tried this and polymorphism-wise it works on my end.
This is the code I ran:
struct SymbolTable {
int sym = 42;
};
struct Node {
Node* parent{ nullptr };
virtual const SymbolTable& Symbols() { return parent->Symbols(); }
};
struct A : public Node {
};
struct B : public Node {
SymbolTable symbols;
const SymbolTable& Symbols() override { return symbols; }
};
int main()
{
B parent;
A child;
child.parent = &parent;
std::cout << child.Symbols().sym << std::endl;
return 0;
}
The output of this is
42
as expected.
Therefore, the method of B is called.
However, be advised that if you have a Node of type A that has no parent the program will crash, because an invalid pointer is accessed (I initialized it to nullptr in this example, and so should you). In this example that would mean changing the type of parent to A. In that case the program will crash with an access violation (because the parent of parent is a null pointer).
So I am creating a Huffman tree, and I am having a hard time overriding a function, and I believe that it is due to a covariance issue. Here is the hierarchy that I am having a hard time with in my code:
class TreeInterface {
public:
TreeInterface() {}
virtual ~TreeInterface() {}
virtual NodeInterface * getRootNode() const = 0;
};
class Tree : TreeInterface
{
public:
Tree()
{}
virtual ~Tree()
{}
Node* getRootNode()
{
return treeRoot;
}
private:
Node* treeRoot;
};
Those work just fine, but its the next block that has issues.
class HuffmanInterface{
public:
HuffmanInterface() {}
virtual ~HuffmanInterface() {}
virtual bool createTree(string filename) = 0;
virtual string encodeMessage(string toEncode) = 0;
virtual TreeInterface * getTree() = 0;
virtual map<char, string> getEncodings() = 0;
};
class Huffman : HuffmanInterface{
public:
Huffman() {}
~Huffman() {}
bool Huffman::createTree(string filename){ }
string Huffman::encodeMessage(string toEncode){ }
string Huffman::decodeMessage(string toDecode){ }
Tree* Huffman::getTree(){ }
map<char, string> Huffman::getEncodings(){ }
So the problem is apparently in the getTree() function, giving the following error
invalid covariant return type for ‘virtual Tree* Huffman::getTree()’:
Tree * getTree();
but as far as I know, Tree* should be a valid covariant of TreeInterface*. replacing Tree* with TreeInterface* makes the program compile, but it's not what I need in my actual program. Any help is greatly appreciated!
class Tree : TreeInterface { ... };
is equivalent to
class Tree : private TreeInterface { ... };
You need to make the inheritance public.
class Tree : public TreeInterface { ... };
I watched a video that can be found at
https://www.youtube.com/watch?v=4F72VULWFvc and I really liked some of the concept for the cases that presented. But I am working with linked list and need selective method execution, for example:
#include <stdio.h>
class A {
public:
A() : next(0) {
if (head == 0) {
head = this;
} else {
A* step = head;
while (step->next != 0) {
step = step->next;
}
step->next = this;
}
}
virtual ~A() {
if (head == this) {
head = 0;
} else {
A* step = head;
while (step->next != this) {
step = step->next;
}
step->next = next;
}
}
virtual void foo() {
// Do nothing...
}
static A* head;
A* next;
};
class B : public A {
public:
B() {}
virtual ~B() {}
virtual void foo() {
printf("function foo\n");
}
};
A* A::head = 0;
int main() {
A a_cls;
B b_cls;
A* step = A::head;
while (step != 0) {
step->foo();
step = step->next;
}
return 0;
}
After instantiating all of the objects, the method foo() of objects of class B need to execute. To achieve this, virtual method foo() is added to class A, with empty body, virtual void foo() {}, and in class B, code is added to the method foo() body.
It works but I do not like it, in the main function it looks like you are doing something at each node, but you are not, it almost feels like a NULL pointer. Is there another creative solution for this?
Note: I am using C++03.
Check out dynamic_cast as a way to check for a particular derived type and only call foo on objects of class B (or a class derived from B):
int main() {
A a_cls;
B b_cls;
A* step = A::head;
B* step_b = 0;
while (step != 0) {
step_b = dynamic_cast<B *>(step);
if (step_b != 0) {
step_b->foo();
}
step = step->next;
}
return 0;
}
This way, there's no need to define an empty foo method on A. Try it out on ideone.
It works but I do not like it, in the main function it looks like you
are doing something at each node, but you are not
In fact you are doing something at each node. What you are doing is the decision to do nothing. Decisions are generally not free and you haven't told us enough about the application to justify the guess that it could be restructured in a way that the decision could be effectively free (made at compile time).
If the decision to do nothing can't be free, then implementing that decision as a call to a virtual function is nearly as low in cost as that decision could possibly be.
It works but I do not like it, in the main function it looks like you are doing something at each node, but you are not, it almost feels like a NULL pointer. Is there another creative solution for this?
Make sure that your base class is a pure abstract class. That way, every call to step->foo(); will most likely do something.
Here's a bare bones example of a heterogeneous list. List::Node is an abstract base class. List::Node::print() is a virtual member function that is implemented only in the concrete classes. List is able to use a generic algorithm to step through the Nodes without having explicit knowledge of the kinds of Nodes it contains.
#include <iostream>
#include <string>
class List
{
public:
class Node
{
public:
Node() : next(nullptr) {}
virtual ~Node() {}
virtual void print() = 0;
Node* next;
};
List() : head(nullptr), tail(nullptr) {}
~List()
{
Node* node = head;
Node* next = nullptr;
for ( ; node != nullptr; node = next )
{
next = node->next;
delete node;
}
}
void addNode(Node* node)
{
if (head == 0)
{
head = tail = node;
return;
}
if ( head == tail )
{
head->next = node;
}
tail->next = node;
tail = node;
}
void print()
{
Node* node = head;
for ( ; node != nullptr; node = node->next )
{
node->print();
std::cout << std::endl;
}
}
Node* head;
Node* tail;
};
class NodeA : public List::Node
{
public:
NodeA(int d) : data(d) {}
virtual ~NodeA() {}
virtual void print()
{
std::cout << "In NodeA::print(), Data: " << data;
}
private:
int data;
};
class NodeB : public List::Node
{
public:
NodeB(double d) : data(d) {}
virtual ~NodeB() {}
virtual void print()
{
std::cout << "In NodeB::print(), Data: " << data;
}
private:
double data;
};
class NodeC : public List::Node
{
public:
NodeC(std::string const& d) : data(d) {}
virtual ~NodeC() {}
virtual void print()
{
std::cout << "In NodeC::print(), Data: " << data;
}
private:
std::string data;
};
int main()
{
List list;
list.addNode(new NodeA(10));
list.addNode(new NodeB(23.45));
list.addNode(new NodeC("abcd"));
list.print();
return 0;
}
Although Austin's solution is perfectly fine, another approach (that I typically prefer) in such situations is to use interface classes and upcasting.
class FooFighter { public: virtual void foo() = 0; };
class A { ... };
class B1 : public A { ... };
class B2 : public A, public FooFighter { ... };
...
int main() {
std::vector<A *> v;
// fill up v
for (int i = 0; i < v.size(); ++i) {
FooFighter * ff = dynamic_cast<FooFighter *>(v[i]);
if (ff) ff.foo();
}
return 0;
}
This lets you keep whether or not a class has foo independent of the rest of your hierarchy. In particular, by examining the class hierarchy of any type you always know whether or not that type implements foo, because it has to inherit from FooFighter. When you use the downcasting approach, you could have multiple children of A that non-trivially implement foo in different ways. This approach also meshes extremely well with IDEs that let you easily examine and traverse the type hierarchies in your code.
I am building a linked list, where nodes are all linked to Head. The Head is derived from node, but the Head requires a pointer to last node. See the comment at the top of code.
/* Base <= node <= node <= node
* | ^
* | ptr to last node |
* -------------------------
*/
class Node {
private:
Node* prev;
public:
explicit Node(Node* parent) : prev(parent) {
Node* foo_ptr = this;
while (foo_ptr->prev != 0) {
foo_ptr = foo_ptr->prev;
}
// foo_ptr points to Base, how can I now change Base::last?
}
};
class Base : public Node {
private:
Node* last;
public:
Base() : Node(0), last(this) {}
};
How can I change change variable Base::last when adding new node, for example:
Node* n = new Base;
new Node(n); // can Node constructor update n->last?
I was thinking to use virtual function to update the variable, but according to this post: Calling virtual functions inside constructors, its a no no so I do not want to do it. So is there a good way of achieving this type of linked list?
Thanks...
http://coliru.stacked-crooked.com/a/213596aa1ffe7602
I added a flag value so we can tell that we actually accessed the Base class:
#include <iostream>
class Node {
private:
Node* prev;
public:
inline void changeBaseLast(Node* base);
explicit Node(Node* parent) : prev(parent) {
Node* foo_ptr = this;
while (foo_ptr->prev != 0) {
foo_ptr = foo_ptr->prev;
}
// foo_ptr points to Base
// now change Base::last
changeBaseLast(foo_ptr);
}
int data;
};
class Base : public Node {
private:
Node* last;
public:
int flag;
Base() : Node(0), last(this), flag(0) {}
};
//Here, we can see that we change the base_ptr to 1.
void Node::changeBaseLast(Node* base) {
Base* base_ptr = static_cast<Base*>(base);
base_ptr->flag=1;
}
int main() {
Node* n = new Base;
new Node(n);
std::cout << static_cast<Base*>(n)->flag << std::endl;
}
If you pull out the part that refers to the derived class and then inline it, there should be no problems with this. Notice, though, that I need to define the functions that refer to the derived class after I define the derived class.
If you're sure that the last node will always be a Base object, then using static_cast<Base*> may not be that bad.
class Base : public Node {
...
// Factory method to create child nodes
Node* getNode(Node* parent) {
Node* newNode = new Node(parent);
last = newNode;
return newNode;
}
}
This one should be even easier to understand and still uses static_cast, for you want to append by means of the Base class.
class Node {
private:
Node* prev;
public:
explicit Node() : prev{nullptr} { }
void setParent(Node *parent) {
prev = parent;
}
};
class Base : public Node {
private:
Node* last;
public:
Base() : Node{}, last{this} { }
void append(Node *node) {
node->setParent(last);
last = node;
}
};
int main() {
Node* n = new Base;
static_cast<Base*>(n)->append(new Node{});
}
Anyway, I don't understand the need of the Base class.
Can't you simply store somewhere (as an example a struct) two pointers, one for the head of the list and one for the last node?
I've just discovered some very odd behavior in my program. I have a tree where every Node is a subclass of Node. I recursively calculate a bounding box by traversing the tree until I reach the unit primitives (i.e. a Cube : Node) at the leaf nodes.
The recursive function getBoundingBox() is declared as virtual and correctly traverses the tree. Leaf nodes override the function and return a unit cube.
However, when I trace the program it appears that the override has no effect on the recursive function getBoundingBox(), even though it works just fine for another function like getName().
Example:
class Node;
typedef shared_ptr<Node> node_ptr;
class Node
{
protected:
vector<node_ptr> mChildren;
public:
virtual string getName() { return "Node";}
virtual BoundingBox getBoundingBox()
{
//Merge Bounding Boxes of Children
BoundingBox bb = BoundingBox();
//For each child
for(vector<node_ptr>::iterator it = mChildren.begin(); it != mChildren.end(); ++it) {
string name = (*it)->getName();//Correctly returns Node or Cube depending on type of (*it)
bb = BoundingBox::Merge(bb, (*it)->getBoundingBox());//Always calls Node::getBoundingBox(); regardless of type
}
return bb;
}
};
class Cube : public Node
{
public:
virtual string getName() { return "Cube";}
virtual BoundingBox getBoundingBox()
{
return BoundingBox::CreateUnitCube();
}
};
Is there some sort of caveat about recursive polymorphism in c++ that I'm missing?
I think your inheritance structure is muddled up. It makes more sense to have a base class Node which may be abstract
class BaseNode {
public:
virtual BoundingBox getBoundingBox() const = 0;
};
and then define the different types of nodes
using node_ptr = std::shared_ptr<BaseNode>;
class Node : public BaseNode
{
std::vector<node_ptr> mChildren;
public:
BoundingBox getBoundingBox() const noexcept
{
BoundingBox bb;
for(auto pc:mChildren)
bb.merge(pc->getBoundingBox());
return bb;
}
};
class Cube : public BaseNode
{
public:
BoundingBox getBoundingBox() const noexcept
{ return BoundingBox::CreateUnitCube(); }
};
Cube isn't a Node as you didn't use public inheritance.
I'm not sure how your actual code even compiles, but try to change it to:
class Cube : public Node