class/struct design; inheritance vs forward declaration - c++

I'm having trouble understanding when/if single/multiple inheritance should be used vs forward declaration & I'd like to get a better understanding of it in the following example. If someone could point me in the right direction, or explain differences between them, it would be much appreciatd.
Following is sample of data structure I'm dealing with;
There exists 1 Parent, 1 SubParent & many different Children types. ie there's many Children per SubParent per Parent. Some Children need access to other Children objects. Children will use similar functions to each other ie ParseSelf/Display/Save/Edit. If Children get changed (ie Edit/Save), also need to update data in SubParent, Parent & possibly other Children.
I'm wanting to know what would be best way to implement something like this? I've come up with two alternatives below. If more clarification/information is needed please let me know.
class SubParent;
class Children;
class Parent
{
...
int iParent;
SubParent *pSubParent;
};
class SubParent
{
...
int iSubParent;
std::list<Children> childrenList;
};
class Children
{
...
int iChild;
int ChildType;
char *pData;
};
versus;
class Parent
{
...
int iParent;
};
class SubParent : public Parent
{
...
int iSubParent;
};
class Children : public SubParent
{
...
int iChild;
int ChildType;
char *pData;
};
Thank you.
EDIT:
Main job of Parent; maintains information about file ie location of SubParent, SubParent size, total size of all data including self.
Main job of SubParent; contains information about Children ie size & location of Children.
Both Parent/SubParent don't really do much else except keep these items upto date.

I would recommend going with the first approach, with the following changes:
Add a member in SubParent that points to the Parent. This will allow you traverse the objects both ways.
class SubParent
{
...
int iSubParent;
Parent* parent;
std::list<Children> childrenList;
};
You should keep a list of Children* in SubParent instead of a list of Chilren if you are going to have different types of Children. If Children will never have any sub-classes, having a list of Children is good enough.
Add a pointer to the SubParent in Children. Again, that will allow you to traverse the objects both ways. Given a Children, you would be able to access its siblings through that pointer.
class Children
{
...
int iChild;
int ChildType;
SubParent* subParent;
char *pData;
};

Related

Saving in binary files

I've been working on a project for the past few days that involves three linked lists.
Here is an example of the header with the nodes and the lists themselves:
class nodeA
{
int data1;
double data2;
nodeA* next;
}
class listA
{
nodeA* headA;
...
}
class nodeB
{
int data3;
double data4;
nodeB* nextB;
}
class listB
{
nodeB* headB;
...
}
class nodeC
{
int data5;
double data6;
nodeC* nextC;
}
class listC
{
nodeC* headC;
...
}
What i'd like to know is how can i save the lists that i declare in my main so that if i close the program and then open it again i can recover the lists data
So lista_vendas::novaVenda needs to call lista_produto::escolheProduto.
To call lista_produto::escolheProduto you need a lista_produto object. Where are you going to get that lista_produto object from?
There's really only three ways this can be done. I don't know which way is the correct way for you, but I'll list them and you can decide.
1) Have a lista_produto global variable, a global list of products. Then lista_vendas::novaVenda can use the global lista_produto to call lista_produto::escolheProduto. This is the simple solution, but global variables are rightly considered bad style. It also means that you program can only have one list of products, is that a problem? Think carefully before trying this solution.
2) Have a lista_produto as a member variable of lista_vendas or no_vendas. I guessing here but perhaps something like this
class no_vendas
{
public:
unsigned int codigoVenda, dia, mes, ano, numeroItens;
double precoTotal;
lista_produto productList; // list of products
no_vendas* proxi; //referencia para o proximo no
};
Now each vendor has a list of products, which makes sense. So lista_vendas::novaVenda now has access to a lista_produto in each no_vendas and it can use that to call lista_produto::escolheProduto. If this makes sense then this is problably the best solution.
3) Pass a lista_produto as a parameter to lista_vendas::novaVenda. Like this
void novaVenda(unsigned int codigoVenda, lista_produto* productList);
So whatever code calls lista_vendas::novaVenda must also supply the lista_produto that it needs.
As I said I don't know which of these possibilities is correct, because I don't know what you are trying to do (and I don't speak Spanish). But this is a problem in the relationships between your different objects. It's up to you to design your classes so that they can access the different objects that they need to work.
You mentioned inheritance in your title, but this doesn't feel like the right thing to do in this case.
This won't help you with your concrete problem at hand but I think you should use standard containers like std::vector<>. Implementing your own linked list is a nice finger exercise but seldom really necessary. That said, you should use std::vector<no_produto> instead of lista_produto:
#include <vector>
std::vector<no_produto> my_lista_produto;
// fill the vector:
my_lista_produto.push_back(my_no_produto_1);
my_lista_produto.push_back(my_no_produto_2);
// ...
// retrieve one item:
const no_produto &p = my_lista_produto[1];
// clear all items:
my_lista_produto.clear();
A complete list of all available methods can be found here.
Concerning your question: The question title mentions inheritance but there isn't any inheritance used in your example. In order to derive class B from class A you have to write
class A {
public:
void func();
};
class B : public A {
public:
void gunc();
};
This means essentially, B can be treated as an A. B contains the content of A and exposes the public interface of A by itself. Thus we can write:
void B::gunc() {
func();
}
even though B never defines the method func(), it inherited the method from A. I suspect, that you didn't inherit your classes properly from each other.
In addition to my initial thoughts about writing you own linked lists, please consider also composition instead of inheritance. You can find more information about the topic at Wikipedia or on Stack Overflow.

Cast Object at Runtime Depending on Instance Variable (C++)

I'm trying to represent a 2 dimensional map of objects. So I have a two-dimensional array of "MapItems":
MapItem* world_map[10][10];
In my specific situation, these MapItems are going to be used to represent Drones, Static Objects (like trees or any obstruction that doesn't move), or empty positions (these objects will be subclasses of MapItem):
class Drone : public MapItem {
int droneId;
...
}
class StaticObject : public MapItem {
...
}
class EmptyPosition : public MapItem {
int amount_of_time_unoccupied;
...
}
Is it a good idea to have an instance variable on the MapItem class that tells what specific type of item it is, and then cast it the proper type based on that? For example:
enum ItemType = {DRONE, STATIC_OBSTRUCTION, EMPTY};
class MapItem {
ItemType type;
...
}
And then when I want to know what is at a position in the map, I do:
MapItem *item = world_map[3][3];
if (item->type == DRONE) {
Drone *drone = dynamic_cast<Drone*>(item);
// Now do drone specific things with drone
...
} else if (item->type == STATIC_OBSTRUCTION) {
StaticObject *object = dynamic_case<StaticObject*>(item);
// Static object specific stuff
...
} else {
...
}
I have not actually tried this, but I assume it's possible. What I'm really asking is this a good design pattern? Or is there a better way to do this?
A "switch on type" indicates a design problem much more often than not.
What you usually want to do is define and implement some virtual functions for the behaviors you care about. For example, you might care about flying into one of the spaces. If so, you might have a function to see if it allows entry. That will return true if a drone is trying fly into open air, or false if it's trying to fly into a tree.
As an aside, if you're going to have derived objects, you need to define the array as container pointers, not actual objects of the base class. Otherwise, when you try to put a derived object into the array, it'll get "sliced" to become an object of the base class.

C++ tree/forest structure for nodes of different class types

\\while implementing a solution found with casting over a a common baseclass
\\ with virtal members.
\\i found out about univeral references, because that is a other question i created a new one:
https://stackoverflow.com/questions/29590429/c-is-it-possible-to-use-universal-references-for-a-tree-forest-with-nodes-that
please refer also to this original question.
I want to organize the hierarchical tree structure of objects with different types.
The solution should do its work at compile time, so i found out that i have to do this with templates at best without any casting.
after some try's that are in the editlog and had some fundamental flaws.
i found a way to split it up in two classes
forest that stores all the nodes and does give them two coordinates the indexnumbers in the vector< vector <...> >
node a template < T > that stores the T Object and the relationship to the other nodes
my idea does not yet have a way to access the memberfunctions of the Objects stored inside the node class, without breaking the unique_pointer that secures the resourcemanagement.
and i would like to know how to ensure typesafty when accessing a object inside the node class.
there may be errors inside the code, i'm quite sure that it will not compile, the question is about the concept.
Questions are inside the comments.
verion 4:
class Forest
{
public:
template<typename T>
{friend class Node<T>;} \\every Node<T> should have access to the forest
Forest();
~Forest();
Forest(const Forest&)=delete; \\does not make any sense to copy or assign the forest to another forest.
Forest operator=(const Forest&)=delete;
int insertroot() \\every tree has a void nullptr seed/root so that the forest does not need to be templatet, returns the treenumber
{ \\implementation
if(this->Nodes.size()==0)
{
std::vector<std::unique_ptr<Node<void> > > h0;
h0.push_back(std::unique_ptr<Node<void>(new Node<void>(nullptr));
this->Nodes.push_back(h0);
}else
{
this->Nodes[0].push_back(std::unique_ptr<Node<void>(new Node<void>(nullptr,this)));
}
return this->Nodes[0].size()-1;
}
Node<void>* getroot(int i) \\ to later allow access to the children and the Objects inside them
{
if(Nodes.size>0){
if((i>0)&(i<Nodes[0].size()))
{
return Nodes[0][i].get();
}
}
private:
std::vector<std::vector<unique_ptr<Node<void> > > nodes; \\is it possible to fill this vector with any Node<T>? its a vector*2 to a unique_ptr to a classpointer with a member pointer to any class. from what i read about templates they create a extra class for every type, so basicly the unique_ptr have a different type and i cannot store different types in a vector without casting?
}
template<typename T>
class Node
{
public:
Node(T n,Forest * Fo) \\ every Node is in the forest and has access to the other nodes and forest information
:object(std::unique_ptr(n)),F(Fo)
{
if(n==nullptr)
{
this->lvl=0;
this->place=F->Node[0].size();
this->parent=-1;
}
}
~Node();
Node(const Node&)=delete;
Node operator=(const Node&)=delete;
T getObject(){return object.get();} \\how does the compiler know the type? see getchild
template<typename C>
{
Node<C> * getchild(int){} \\not yet exsisting implementation of get child[int] how do i teach the compiler what int responds to what type?
\\when i understand templates correct then Node<C> are different Classes for every C??
addChild(C c)
{
Node * n=new Node(c,this->F);
n->parent=this->place;
n->lvl=this->lvl+1
if(F->nodes.size()<=n->lvl)
{
n->place=0;
h0=std::vector<unique_ptr<Node<C>> >;
h0.push_back(unique_ptr<Node<C>(n))
F->Nodes.push_back(h0); \\are vector<uniptrNode<C> > and vector<uniptrNode<void>> compatible?
}else
{
n->place=F->nodes[n->lvl].size();
F->Nodes[n->lvl].push_back(unique_ptr<Node<C> >(n));
}
this->children.push_back(c->place);
}
}
private:
int parent,place,lvl;
std::vector<int> children;
unique_ptr<T> object;
Forest * F;
}
does anyone know a way to implement a container like this?
maybe there is some abstract type type i did not find out about, so do that i can add a method type getnodetype(int) or checknodetype(int,type), could i assign this with auto nodex=y->getObject()? But then how does the compiler know what methodes nodex has and does not has?
EDIT: i removed the original Post because v4 is very close to a working solution version 1-3 should be in the editlog
I think you need something like boost.any or QVariant.

Design choice regarding manipulation of main loop from treegraph

I'm creating a simple game for programming practice on bigger projects and am currently stuck at a crossroad.
The game uses a treegraph structure to store all the entities of the game, all extending from the base class called TreeNode that implements some basic functions such as attaching and detaching children from themselves as well as their position in the 2D world.
My problem is that I want to create a sort of "Action Node" that upon collision with the player allows various events to take place, such as changing the song being played, trigger a pause with subsequent dialogue, ending the stage etc etc.
My question is, how would i implement this in a decent way that doesn't beat my efforts of code isolation to a bloody pulp? I was thinking of making a new class with a std::function member that i can program to do what i want it to do, but that way would mean completely breaking code encapsulation by handing it a reference to my master class that contains ALL data in the entire game.
Collision is currently implemented something like this:
std::vector<std::pair<&TreeNode, &TreeNode>> vCollision;
MasterNode.checkCollision(vCollision);
checkCollision gets called with a reference to the vector, invokes collision checks recursively on the rest of the graph and fills the vector with pairs of different entities that have collided. (this is in the update loop.)
I also need to figure out a way to be able to call said std::function from this list since pointers to the base class wont have access to members of derived classes.
A tree structure is a container that can be used with different data types. Because of this, it is a good candidate for templates.
Since you have your tree working, factor out the data type to a template parameter.
For example, given a node:
struct Tree_Node
{
struct Tree_Node * left_subtree;
struct Tree_Node * right_subtree;
Some_Data_Type node_data;
};
You can factor out the data type using templates:
template <class Node_Data_Type>
struct Tree_Node
{
struct Tree_Node * left_subtree;
struct Tree_Node * right_subtree;
Node_Data_Type node_data;
};
You would declare a tree node as:
struct Player_Data;
Struct Moves_Data;
struct Tree_Node<Player_Data>; // For a tree of Player_Data
struct Tree_Node<Moves_Data>; // For a tree of Moves_Data
An alternative is to use inheritance for the node data.
struct Node_Data_Base
{
virtual bool is_equal(Node_Data_Base * p_node) const = 0;
virtual bool is_less(Node_Data_Base * p_node) const = 0;
bool operator==(Node_Data_Base * p_node) const
{
return is_equal(p_node); // Dispatch to child.
}
bool operator<(Node_Data_Base * p_node) const
{
return is_less(p_node); // dispatch to child.
}
};
struct Tree_Node_Inheritance
{
struct Tree_Node * left_subtree;
struct Tree_Node * right_subtree;
Node_Data_Base * p_data;
};
Also, review the std::map data type.

Front-end/Back-end design: how to absolutely dissociate the back-end from the front-end?

My question is: (is the above|what is) the right way to create a non intrusive front-end?
I am explaining my problem with a simplified example.
I have a back-end implementing a binary tree:
// Back-end
struct Node
{
Label label;
Node* r, l;
};
I would like now to implement the front-end to print the tree graphically. So my idea is to extend the back-end with graphical properties by wrapping it :
// Front-end
struct Drawable
{
uint x, y;
};
class Visitor;
template <class T> struct GNode : public Drawable
{
T* wrapped;
template <class V> void accept(V& v); // v.visit(*this);
}
There is a problem now to create a visitor printing the binary tree:
struct Visitor
{
void visit(GNode<Node>& n)
{
// print the label and a circle around it: ok.
if (n.wrapped.l) // l is a Node, not a GNode, I can't use the visitor on it
// Problem: how to call this visitor on the node's left child?
// the same with n.wrapped.r
};
};
As explained in comments, the back-end does not use my extended class.
Writing GNode "is-a" Node is not a solution neither since I would have to put the accept() method in the Node class as virtual and override it in GNode but I can't modify the back-end. Then, someone could say too that there is no need to declare accept() in the back-end, downcasting Node* to GNode* would work. Yes it works, but it downcasts...
In my case, I have ~10 kinds of nodes (it is a graph), so I am looking for something elegant, flexible, with as few lines of code as possible (hence the wrapper template idea) :)
Thank you very much.
To absolutely disassociate code is impossible. They have to talk. If you really want to enforce decoupling to the maximal extent, some sort of IPC/RPC mechanism should be used and have two different programs.
That said -- I don't like visitor patterns.
You have a Graphical object, which is linked against a Behaving object. Maybe there are rules between behavior and the graphics, e.g., boundaries can't overlap.
You can do your entity relationship whatevers between the Graphicals and the Behaves, that's a biz logic question...
You will need some thungus that holds your drawing context (img, screen, buffer).
class DrawingThungus {
void queue_for_render(Graphical*);
void render();
};
Your Graphical will have either an inheritance or a composition relationship with behaves.
At any rate, they will have the interface needed to do Drawing.
//abstract base class class Graphical {
get_x();
get_y();
get_icon();
get_whatever();
};
If you are finding that your Render is becoming case-based depending on the kind of Graphical, I suggest pushing the cases over to the Graphical, and refactoring to have a get_primitives_list(), wherein the needed primitives are returned for Graphical to return (I am presuming that at some level, you have core primitives, lines, circles, arcs, labels, etc).
I have always found that OO analysis lends itself to wasting mental energy and should be done only enough for the task at hand. YAGNI is a tremendous principle.
If your wrapper class (GNode) didn't have to maintain any state across visits (i.e., it only had one field - the wrapped Node object), you could use a pointer or a reference to the wrapped object instead of a copy, and then you would be able to wrap any node at runtime.
But even if you do maintain state (the x,y coordinates), don't you really just infer it from the wrapped object? In that case, wouldn't it be better to separate your visited class from the inferred data? For instance, consider this implementation:
// This is an adapter pattern, so you might want to call it VisitorAdapter if you
// like naming classes after patterns.
template typename<T>
class VisitorAcceptor
{
private:
T& wrapped;
public:
VisitorAcceptor(T& obj)
{
wrapped = obj;
}
template <typename VisitorT>
void accept(VisitorT& v)
{
v.visit(wrapped);
}
};
struct GNode
{
uint x, y;
shared_ptr<GNode> l,r; // use your favourite smart pointer here
template <typename VisitorT>
void accept(VisitorT& v)
}
// You don't have to call a visitor implementation 'Visitor'. It's better to name
// it according to its function, which is, I guess, calculating X,Y coordinates.
{
shared_ptr<GNode> visit(Node& n)
{
shared_ptr<GNode> gnode = new GNode;
// calculate x,y
gnode->x = ...
gnode->y = ...
if (n.l)
gnode->l = VisitorAdapter(n.r).accept(*this);
if (n.r)
gnode->r = VisitorAdapter(n.l).accept(*this);
};
};
Now you can have a different visitor for drawing:
struct GNodeDrawer
{
void visit(GNode& gnode)
{
// print the label and a circle around it: ok.
if (n.r)
visit(n.l);
if (n.r)
visit(n.r);
};
};
Of course, if you don't need all the extensibility the visitor pattern offers, you can throw it away altogether and just walk the the tree recursively with XYCalculator.visit calling itself.
Personally, I would make a drawing class with overloaded functions (one for each node type) rather than trying to hook into the existing structure with some sort of complicated inheritance solution.
I finally found an "elegant" solution with the decorator design pattern.
This pattern is used to extend an object without changing its interface.
GNode decorates/extends Node:
template <class T> struct GNode : public T, public Drawable
{
virtual void accept(Visitor& v); // override Node::accept()
}
As you can see, it requires a little change in the back-end structure:
struct Node
{
Label label;
Node* r, l;
virtual void accept(Visitor& v);
};
That's it ! GNode is-a Node. We can now create a binary tree of GNodes and visit it thanks to the virtual method accept() in the back-end structure.
In the case when we absolutely follow my question, i.e. we can't modify the back-end and it doesn't have the virtual entry point presented above, we can add features to GNode mapping the Node it wraps to itself. So that a visitor visiting GNodes (that can only have access to its sons) can find the GNodes of its sons. Yes, this is the virtual keyword job with the above solution! But we never know if someone would be in this case for real.
As a conclusion to all this: the way you express a problem always influences the way to resolve it.