c++ BST and file handling - c++

i am interested in creating a car register program:
menu for user to add, delete, find, edit(change a particular detail about the car) a car and view all the cars. this is then stored in memory using a binary search tree. all the cars are to be written out from memory into a csv file. also when loading the system it should read all the cars back in
car has 2 types petrol and electric.
every car has attributes car id, owner, make, model, numberplate
a petrol car has attributes miles, topup
an electric car has attributes power, miles
class car
{
string id
string owner
string make
string model
string numberplate
virtual getkey()//gets key being searched etc.
readfile();
writefile();
};
class petrol : public car
{
string miles
string topup
};
class electric : public car
{
string power
string miles
};
data structure:
class node
{
car *ptr
node *left
node *right
};
class tree
{
///insert delete etc.
};
would this be a practical class design and what functions might need to be included?

The problem with initial BST and Linked List implementations is that they either force you to use a specific data type or inherit from that data type (such as yours). If I want a BST for fruit, I can't use your tree, because your tree is dedicated to cars.
I suggest an abstract node class and deriving your data classes from the node class:
struct Node
{
boost::shared_ptr<Node> left;
boost::shared_ptr<Node> right;
// Interface functions for descendants
virtual bool is_less_than(boost::shared_ptr<Node> other_node) const = 0;
virtual bool is_equal_to(boost::shared_ptr<Node> other_node) const = 0;
};
I still believe the best design is to use a template:
template <class User_Data_Type>
class Node
{
public:
boost::shared_ptr<Node> left;
boost::shared_ptr<Node> right;
User_Data_Type m_data;
};

Related

Implementing a base class tree with arbitrary amount of child nodes of derived types?

I want to implement a GPA calculator program with the following structure: A collection of years is a tree of years, a year is a tree of semesters, and a semester is a tree of courses. These types will all be derived from one base class called "Container". Since we dont know how many classes could be contained in a semester, i want to have a vector of pointers to its children so that we can add an arbitrary amount of course nodes. Would the following implementation work?
template <typename ContainerType, typename ChildType>
class Container
{
protected:
// Node class definition.
class Node
{
public:
ContainerType data; // contents of the node.
vector<Node*> child; // links to the node's children.
// Node constructor functions:
Node() { }
Node(const ContainerType &theData) : data(theData) { }
};
protected:
Node *current; // Points to the current node
Node *parent; // Points to current node's parent
};
Im hoping that every time i add a child node, I can increase the amount of child Node pointers as needed. Is this possible? I have a feeling that since the container's node pointers will point to nodes of different types, that this might cause issues.

Getters in recursive class with pointers to other instances of the class

For a school project, I need to build a BinarySearchTree for a tuple of index and value of type T and I decided to make it using left and right child pointers (to other instances but bear with me).
To make the class a bit more realistic and readable, I built 3 different classes: Tree, BinaryTree, and BinarySearchTree with inheritance.
I declared the getter and the setter of the left and right children in the BinaryTree class and the class looks like this:
template <typename T>
class ArbreBinaire : public Arbre<T>
{
private:
ArbreBinaire<T>* _leftChild;
ArbreBinaire<T>* _rightChild;
public:
ArbreBinaire(lu index = 0, T element = T(0), ArbreBinaire<T>* lchild = nullptr, ArbreBinaire<T>* rchild = nullptr) :
Arbre<T>(index, element), _leftChild(lchild), _rightChild(rchild) {};
virtual ArbreBinaire<T>* getLC() const { return _leftChild; }
virtual ArbreBinaire<T>* getRC() const { return _rightChild;}
void setLC(ArbreBinaire<T>* lc) { _leftChild = lc; lc->setParent(this); }
void setRC(ArbreBinaire<T>* rc) { _rightChild = rc; rc->setParent(this); }
virtual ~ArbreBinaire() = default;
};
And in my BinarySearchTree, in a few places I need to go through my tree (to insert or search for exemple).
So here comes finally my question: What is the best way to get the left child of my object, which is of type BinarySearchTree and to keep the continuity (BST that has BST left child and BST right child)
I thought of multiple options:
virtual getter and setter and redefining it in every derived class but there are 2 other "problems" with that solution.
Should I have 2 other members in my BST, which would be of type BST* and basically point to the same object than the ones in my BinaryTree ?
Should I just redefine my getters to return a dynamic_cast version like this : BST<T>* getLC() { return dynamic_cast<BST<T>*> (this->BinaryTree::getLC()) } ?
Putting all my members, getters and setters in my BST class (but that goes opposite to the definition of a BinaryTree, the base class : a BinaryTree with no children is not a BinaryTree)
3.Just casting every time i need to get my left or right child
4.Casting everytime i need to use a method in BST (derived class) ?
5. Any other suggestions?

Would making a binary search tree out of a struct over a class node be bad?

I'm not sure if i should.. or should not use a struct to create a binary search tree, the other option is to create the nodes out of a separate node class. with a data, left and right. Which one is better? And why?
heres my code for the BST
template <typename T>
class BST : public SearchableADT<T>
{
public:
BST(void){ head = NULL; numnodes = 0; }
virtual ~BST(void);
virtual int loadFromFile(string filename);
virtual void clear(void);
virtual void insertEntry(T info);
virtual void deleteEntry(T info);
virtual bool isThere(T info);
virtual int numEntries(void);
//needed for comparison to AVL
int BST<T>::height(t_node* tPTR);
protected:
struct t_node
{
string data;
t_node *L;
t_node *R;
};
int numnodes;
t_node* head;
t_node* cPTR; //current pointer
t_node* pPTR; //parent pointer
t_node* tPTR; //temporary pointer
}; // end of class BST
I'm not sure if you understand the difference between struct and class but basically:
struct
Has public access for all of its members by default and
class
Has private access for all of its members by default.
You can achieve the same thing with both of them but many programmers, including myself, tend to use structs for POD objects (Plain Old Data) for straight up access (It makes it easier to write less).
That said, I think you should put your Node class outside in a different file since the BST and Node classes are very different. Since you gave your BST class a template, I am assuming that you are gonna use more than just the Node class, which gives more reason to separate the files for the projects that you might not use the Node class. If you aren't going to use more than just a Node class, you might consider removing the template and defining the Node struct/class inside the BST class!
It is better to create two classes, one for the BST and another for the node. They are two different abstractions. A node is a simpler abstraction whose main purpose is to hold the data necessary to define a BST. A BST is a higher level abstraction. It's a collection class with its own constraints and expectations.

Creating an object that is part of multiple classes

I am trying to build a program where I wanted to create an object that is part of two classes.
I have the class Student and then I have a class for Node. And I want to create an object that is at the same time a Student and a Node. I tried doing this:
Student James;
James = new Node;
But that doesn't work.
Any help on how to do this? Thanks.
Use inheritance: http://en.wikipedia.org/wiki/Inheritance_%28computer_science%29
class Node {
//....
}
class Student : public Node {
//....
}
Student James;
You can treat object James as Node via pointer to base object:
Node * p = &James;
What you're looking for is multiple inheritance:
class MyClass : public Student, public Node
{
// ...
};
MyClass James;
You may want to read up on this feature of C++, it's not without its pitfalls.
EDIT
The question here is: what is the relation between Student and Node?
If Student is a kind of Node (e.g. you have students, teachers, etc and you all want these to behave as nodes), then you can simply inherit Student from Node:
class Student : public Node
{
// ...
};
Student James;
In this case, you can also do:
Node* James = new Student();
// do stuff with James
delete James;
If Student and Node are independent, you have to ask yourself if you really want an object that can behave as both at the same time. Perhaps you only need an object that pairs a Student and a Node:
struct MyStruct
{
Student myStudent;
Node myNode;
};
MyStruct James;
If you actually need an object that can behave as both Student and Node (even though those two things are independent) then you'll need multiple inheritance.
Use polymorphism:
Class Base
{
}
class Student : public Base
{
}
class Node : public Base
{
}
Now:
Student s;
Node n;
Base* b = &s;
b = &n;

multiple linked lists for different objects in c++

consider these classes (simplified)
class Character
{
public:
char name[20];
char type[20];
int strength;
};
class inventoryItem
{
public:
char name[20];
};
class weapon: public inventoryItem
{
public:
int magical resistance;
};
class spell: public inventoryItem
{
public:
int magical power;
};
i have written a class for a linked list (not allowed to use stl list)
class list
{
public:
struct listItem
{
listItem* objectPointer;
listItem* pnext;
}*phead;
list()
{
phead=NULL;
}
bool isEmpty(){
if (!phead)
return true;
else
return false;
}
void addToBack(listItem *itemtoadd)
{
listItem *ptemp;
listItem *ppast;
listItem *pNewItem;
pNewItem=new listItem();
pNewItem->objectPointer=itemtoadd;
pNewItem->pnext=NULL;
if (phead==NULL)
phead=itemtoadd;
else
{
ptemp=phead;
while(ptemp)
{
ptemp= ptemp->pnext;
}
ptemp->pnext=itemtoadd;
}
}
};
I have cut this down a lot but my question is , is there an easy way to create linked lists for all these using the same list class ? or am I wasting my time ?
every time I have tried it cant convert the pointer from type 'weapon' to type 'listitem'
I need a list of characters and a list of each weapon or spell for that character
I'm still a beginner with OOP and pointers ,
the program I have now compiles and I have a list of characters working , however the list is not managed by the class its managed within some other functions, I'm hoping there's a way for one class to deal with it all , can anyone help explain it to me ?
Take a look at C++ Templates. Using templates you can have one list class in terms of reading/writing code, but you can have a list of weapons, a list of items or a list of anything else without having to write WeaponsList, ItemsList and SomethingElseList classes separately.
The simple answer is to do this
struct listItem
{
void* objectPointer;
listItem* pnext;
}*phead;
A void pointer will allow you to store a pointer to anything. Of course it's then entirely up to you to make sure that you don't lose track of what kind of object you are pointing to. So this approach is risky. The safer approach is templates as has been suggested.
You could use:
enum item
{
WEAPON,SPELL
}
class list {
public:
struct listItem {
union {
weapon *weaponPointer;
spell *spellPointer
} object;
item objType;
listItem* pnext;
}*phead;
however the catch is you have to access the type member to determine what type of item you are accessing.