Inheritance, selective method execution - c++

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.

Related

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

How to make linked list work with multiple instances of classes?

I have
class A{
}
class B : virtual public A{
extra property 1
}
class C : virtual public A{
extra property 2
}
class D : virtual public A{
}
class E : virtual public B, virtual public C, virtual public D{
extra property 3
}
And here's my linked list's insert function:
template <typename T>
class LinkedList {
Node<T> *start;
Node<T> *current;
public:
void insert (T newElement)
{
if ( isEmpty() )
{
insertToStart(newElement);
}
else
{
Node<T> *newNode = new Node<T>;
newNode->info = newElement;
newNode->next = NULL;
current = start;
while (current->next != NULL)
{
current = current->next;
}
current->next = newNode;
}
}
Now I would like to create a single linked list that will store all instances of B, C and D without losing the additional attribute of each child class. How can I achieve this using pointer?
I've tried the solution provided here, but it gives me this error: taking address of temporary [-fpermissive].
Linkedlist<A*> list;
B b;
list.insert(&b);
The following piece of code compiles fine with gcc 4.8:
#include <list>
class A
{
};
class B : virtual public A
{
};
int main()
{
std::list<A*> l;
B* b = new B();
l.push_back(b);
B bb;
l.push_back(&bb);
return 0;
}

How can i get this Linked List to work properly?

I'm very new to linked lists and i can't seem to figure out why this isn't working.
The program doesn't crash and the compiler shows no errors but doActions() never runs.
This is the code for the function, it's called in the main loop.
void Action()
{
clsParent* pCurrent;
pCurrent = pHead;
while(pCurrent != NULL)
{
clsPlayer* pPlayer;
pPlayer = dynamic_cast<clsPlayer*>(pCurrent);
if(pPlayer != NULL)
{
pPlayer->doActions();
}
pCurrent = pCurrent->pNext;
}
}
This is supposed to call doActions() for every single player in the list (although there's only one).
doAction() worked perfectly fine before i tried to implement linked lists into the code so i know it isn't that. For those curious about what it does, it checks if the player is jumping and moves the player accordingly.
EDIT: I've noticed that i can put other functions in and it will work
This works:
void clsPlayer::jump()
{
if(onGround)
{
jumping = true;
yPos -= gravitySpeed;
animationState = 3;
}
}
While this doesn't
void clsPlayer::doActions()
{
if(!onGround)
{
yPos += gravitySpeed;
}
if(jumping)
{
jumpTimeCounter++;
yPos -= 20;
if(jumpTimeCounter > 10)
{
jumping = false;
jumpTimeCounter = 0;
}
}
}
pCurrent if of type clsParent or a subclass of it. The dynamic_cast to type clsPlayer will always fail and return null.
Maybe there is a member data and you should use something like (the cast may even not be necessary):
clsPlayer* pPlayer;
pPlayer = dynamic_cast<clsPlayer*>(pCurrent->data);
From the code you posted I would offer you the following proposed solution:
template<T>
class ListNode
{
public:
T* m_pNext;
};
class Base : public ListNode<Base>
{
public:
Base();
virtual ~Base();
virtual void doActions() = 0;
};
class Derived1 : public Base
{
public:
Derived1();
virtual ~Derived1();
virtual void doActions();
};
class Derived2 : public Base
{
public:
Derived2();
virtual ~Derived2();
virtual void doActions();
};
void action()
{
Base* pCurrent = pHead;
while (pCurrent != NULL)
{
pCurrent->doActions();
pCurrent = pCurrent->m_pNext;
}
}
Things to note:
ListNode is a template class, and your base class (in your example, clsParent) inherits from it.
The base class declares doActions as a pure virtual function, so that derived classes may define their own specific implementation.
As a result of 1 & 2, notice that the loop to walk through the list and call the doActions method is simplified as we now avoid the cast.

Decorator or abstract base class? Neither seem right

I'm writing an interface which basically has two methods next which tries to get the next value and prev which returns the previous value.
struct foo
{
virtual boost::optional<int> next() = 0;
virtual int prev() = 0;
};
The interface will basically be used by first calling next, and if that fails it is possible to get the previous value with prev. prev is not as trivial as in this example, some other stuff should happen for prev values. The prev method works pretty much the same for all classes and I would like to provide a default implemention of it.
I have to ways of implementing this, neither of which I like:
First possibility is an abstract base class instead of interface.
struct abstract_foo : public foo
{
int prev_;
virtual boost::optional<int> next()
{
boost::optional<int> val = do_next();
if(val)
prev_ = *val;
return val;
}
int prev()
{
return prev_;
}
virtual boost::optional<int> do_next() = 0;
};
However, it breaks the interface, now one either have to remember to call abstract_foo::next or be forced to implement a rather ugly do_next.
Another way is using a decorator:
struct foo
{
virtual boost::optional<int> next() = 0;
virtual int prev()
{
throw not_implemented();
}
};
struct foo_decorator : public foo
{
std::unique_ptr<foo> foo_;
int prev_;
foo_decorator(std::unique_ptr<foo>&& foo)
: foo_(std::move(foo))
{
}
boost::optional<int> next()
{
boost::optional<int> val = foo_->next_value();
if(val)
prev_ = *val;
return val;
}
int prev()
{
return prev_;
}
};
Here the, not_implemented just screams for accidents where users think they can use prev directly from the base class.
Does anyone have a good suggestion for good design? Or should I simply have some kind of helper class that help implementing it manually in derived classes?
Your first option is actually close to the preferred way, which would be as follows:
class foo
{
public:
boost::optional<int> next()
{
boost::optional<int> val = do_next();
if(val)
prev_ = val;
return val;
}
int prev()
{
return prev_;
}
private:
int prev_;
virtual boost::optional<int> do_next() = 0;
};
Note how next() and prev() are non-virtual, and do_next() is private. Public non-virtual interface calls private virtual implementation.
In the second option, why not implement prev already in the base class:
struct foo
{
public:
virtual boost::optional<int> next() = 0;
int prev()
{
return prev_;
}
protected:
int prev_;
};
struct foo_decorator : public foo
{
std::unique_ptr<foo> foo_;
foo_decorator(std::unique_ptr<foo>&& foo)
: foo_(std::move(foo))
{
}
boost::optional<int> next()
{
boost::optional<int> val = foo_->next_value();
if(val)
prev_ = *val;
return val;
}
};