Calling virtual function on parent pointer - c++

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).

Related

How can I access a child class member stored in a parent class?

I was assigned to create a sparse matrix. In the process, I got into a problem. I realized I could not access a member of a child class that was stored in a parent class.
I 'googled' my problem and what I got was that there were some casting problems. I tried it out and did not work either.
Sample code:
main.cpp
#include <iostream>
template <typename T>
class Node
{
public: // public for example purposes
Node<T> *down, *right;
public:
explicit Node(Node<T> *d, Node<T> *r) : down(d), right(r) {}
};
template <typename T>
class HNode : public Node<T>
{
private:
unsigned idxValue;
public:
HNode(unsigned iv) : idxValue(iv), Node<T>(nullptr, nullptr) {}
};
template <typename T>
class ENode : public Node<T>
{
public: // public for example purposes
unsigned row;
unsigned col;
int value;
public:
ENode(unsigned r, unsigned c, int v) : row(r), col(c), value(v), Node<T>(nullptr, nullptr)
{}
};
int main(void)
{
Node<int> *root;
root = new Node<int>(nullptr, nullptr);
root->right = new HNode<int>(0);
root->down = new HNode<int>(0);
root->right->down = new ENode<int>(0, 0, 10);
std::cout << root->right->down->value << '\n';
}
This is the error I get:
error: no member named 'value' in 'Node<int>'
std::cout << root->right->down->value << '\n';
root is a Node pointer. root->right is another Node pointer. root->right->down is--you guessed it--a Node pointer.
When you do [...]->value, you're dereferencing that Node pointer, which gives you a Node, and then trying to get the value member on it. But Node has no value member!
You could attempt to cast your Node pointer into an ENode pointer, using dynamic cast. Which would look like:
Node *n = root->right->down;
if(ENode *en = dynamic_cast<ENode*>(n)) {
std::cout << en->value << std::endl;
} else {
std::cout << "That's not an ENode!" << std::endl;
}
But to do this, you'll need to make Node polymorphic (which you can see detailed here).
Also note that in production code, you should be checking to make sure root, root->right and root->right->down are all non-null before going ahead and dereferencing them.
The root class Node only has pointers to other Node's it does not know about what derived classes they might be.
It is "usually" best to have the correct interface in the base class to get results/values from the different kind of derived classes.
So for example if you have a base class animal:
class animal
{
virtual int number_of_limbs() = 0;
}
Then the derived class pig:
class pig: public animal
{
int number_of_limbs() override { return 3;}
}
By doing this the "interface" to the class is generic but each derived/specialisation can have it specific value.
In your case you probably just need a function called virtual int get_value() in your base class and then implement that in your ENode class...
(note all code above is pseudo code only)

Inheritance, selective method execution

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.

C++ Updating a variable in object of derived class via pointer

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?

Deep copy of binary tree

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();

Custom Object Factory

My library uses the Object Factory technique to create "Nodes" that have a specific purpose. By default these Nodes do their job but are quite basic. I want to allow the users of my library to be able and create a sub-class of the provided "Node" class to define their own functionality while keeping the base functionality of a node intact.
Here is some example code to demonstrate my question:
class Node
{
int SomeValue;
public:
Node(int Value)
{
SomeValue = Value;
}
~Node()
{
// Cleanup the node
}
};
class NodeFactory
{
std::vector<Node*> Nodes;
public:
void CreateNode(int Value)
{
Nodes.push_back(new Node(Value));
}
};
This shows the basic Object Factory technique, now for my question.
Can I add a function to the "NodeFactory" such as "void SetType()" and be able to pass in a sub-class of "Node" which in turn will have it create that sub-class during the "CreateNode" function?
Thank you very much for your time it is greatly appreciated.
EDIT:
The usage of "void CreateNode()" is abstracted away from the end user thus my curiosity towards a "void RegisterType()" function where the user can register their sub-class for the factory to create instead of the base-class I provide.
EDIT:
A more concise way to phrase the question would be as follows: How can I let the user tell the factory to create instances of their sub-class, if they've defined one, instead of my default base-class? I want to thank everyone again for their time and effort in answering this question.
I think the problem here is combining the following two requirements:
You want to use the quite simple function void CreateNode(int) to create any node.
You want the user to be able to create new nodes derived from Node and use your factory to create them.
Now what I would suggest is something similar to R Sahu however without following the Factory pattern as strictly as he did.
You could get the functionality you seek by requiring your users to pass a small Creator-object to your factory. (Note that this is deviating a bit from the classical Factory-pattern. As you basically make your NodeFactory into a delegator using the creator-classes.)
class NodeCreator {
public:
virtual Node* create(int) = 0;
virtual ~NodeCreator() = default;
};
class DefaultNodeCreator : public NodeCreator {
public:
virtual Node* create(int value) {
return new Node(value);
}
};
Now I as a user will create my own node:
class MyNode : public Node {
private:
int otherValue;
public:
MyNode(int nodeValue, int otherValue )
: Node(nodeValue), otherValue(otherValue)
{}
// Implement other functionality...
};
class MyNodeCreator : public NodeCreator { 
private:
// I added otherNodeValue to show that Creators can have a state.
int otherNodeValue;
public:
MyNodeCreator(int otherNodeValue ) : otherNodeValue(otherNodeValue) {}
virtual Node* create(int value) {
return new MyNode(value, otherNodeValue);
}
};
Now finally in your Factory class you need to set it like this:
class NodeFactory
{
std::vector<Node*> Nodes;
std::unique_ptr<NodeCreator> activeCreator;
public:
NodeFactory() {
setNodeCreator(nullptr);
}
void createNode(int Value)
{
Nodes.push_back( activeCreator->create(Value) );
}
void setNodeCreator( std::unique_ptr<NodeCreator> creator ) {
if (creator == nullptr) {
activeCreator.reset( new DefaultNodeCreator() );
else {
activeCreator.reset(creator);
}
}
};
To use it from main:
int main() {
NodeFactory nf;
nf.createNode(1); // Creating Node(1)
nf.createNode(2); // Creating Node(2)
nf.setCreator( new MyNodeCreator(5) );
// Any nodes created now will be of type MyNode
// with otherNodeValue == 5.
nf.createNode(2); // Creating MyNode(2, 5)
nf.createNode(3); // Creating MyNode(3, 5)
}
A final note:
If you intend for your users to implement subclasses of Node and use these with polymorphism as shown above, it is important that you declare Node's destructor as virtual. You have no guarantee that your users will not use dynamic allocation in their subclasses, so it is your responsibility to ensure that their destructors get called.
A Factory Pattern is meant to create objects with an indirect reference. For example, the user should be able call:
Node* node = Factory::createNode("MyNodeType");
If there is a Factory that can create such a Node, then the function returns with a pointer to a MyNodeType object. Otherwise, it return NULL.
In order for this function to work, a Factory has to be registered that can construct objects of type MyNodeType. We will have to trust that such a Factory creates Nodes of that type.
The classes involved in this patter:
The abstract base class Node.
The abstract base class Factory.
Concrete sub-class of Node called MyNodeType.
Concreate sub-class of Factory. Let's call it MyNodeTypeFactory.
Here's such a skeletal structure.
Node.h:
class Node
{
virtual ~Node() = 0;
};
Factor.h:
#include <string>
class Factory
{
public:
static void registerFactory(std::string const& productType,
Factory* factory);
static Node* creatNode(std::string const& productType);
private:
virtual Node* createNode();
};
Factory.cc:
#include <map>
typedef std::map<std::string, Factory*> FactoryMap;
static FactoryMap& getFactoryMap()
{
static FactoryMap factoryMap;
return factoryMap;
}
static void registerFactory(std::string const& productType,
Factory* factory)
{
getFactoryMap()[productType] = factory;
}
static Node* creatNode(std::string const& productType)
{
FactoryMap& factoryMap = getFactoryMap();
FactoryMap::iterator iter = factoryMap.find(productType);
if ( iter == factoryMap.end() )
{
// Unknown product.
return NULL;
}
return iter->second->createNode();
}
MyNodeType.h:
#include "Node.h"
class MyNodeType : public Node
{
MyNodeType() {}
virtual ~MyNodeType() {}
};
MyNodeTypeFactory.h:
#include <Factory.h>
class MyNodeTypeFactory : public Factory
{
public:
virtual Node* createNode();
};
MyNodeTypeFactory.cc:
#include "MyNodeTypeFactory.h"
struct RegistrationHelper
{
MyNodeTypeFactorHelper()
{
Factory::registerFactory("MyNodeType", new MyNodeTypeFactory());
}
};
static RegistrationHelper helper;
Node* MyNodeTypeFactory::createNode()
{
return MyNodeType();
}
You probably even don't need a RegisterType()... The simplest way is to use C++11 (it allows you to derive nodes w/ different, than a base Node, constructor signatures):
#include <iostream>
#include <memory>
#include <string>
#include <type_traits>
#include <vector>
class Node
{
int SomeValue;
public:
Node(int Value)
: SomeValue{Value}
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
// ATTENTION Make destructor virtual!
virtual ~Node()
{
// Cleanup the node
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
class SomeOtherNode : public Node
{
std::string SomeStringValue;
public:
SomeOtherNode(int Value, const std::string StringValue)
: Node{Value}
, SomeStringValue{StringValue}
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
~SomeOtherNode()
{
// Cleanup the string node
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
class NotARealNode
{
int SomeValue;
public:
NotARealNode(int Value)
: SomeValue{Value}
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
~NotARealNode()
{
// Cleanup the node
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
class NodeFactory
{
std::vector<std::unique_ptr<Node>> Nodes;
public:
template <typename NodeType, typename... Args>
typename std::enable_if<
std::is_base_of<Node, NodeType>::value
>::type CreateNode(Args&&... args)
{
Nodes.push_back(
std::unique_ptr<NodeType>{
new NodeType{std::forward<Args>(args)...}
}
);
}
};
int main()
{
NodeFactory f;
f.CreateNode<Node>(123);
f.CreateNode<SomeOtherNode>(123, "Hello");
#if 0
// ATTENTION It wont compile, cuz NotARealNode is not a child of Node!
f.CreateNode<NotARealNode>(123);
#endif
return 0;
}
Output:
zaufi#gentop>/work/tests> g++ -std=c++11 -o fff fff.cc
zaufi#gentop>/work/tests> ./fff
Node::Node(int)
Node::Node(int)
SomeOtherNode::SomeOtherNode(int, std::string)
virtual Node::~Node()
virtual SomeOtherNode::~SomeOtherNode()
virtual Node::~Node()
You could (should?) use polymorphism for that. Just derive from NodeFactory (make CreateNode a virtual function) and have it spawn Nodes of your desired type. Of course you would have to move the Nodes vector into a different class.