Creating an object that is part of multiple classes - c++

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;

Related

Change Object type based on inheritance

I have the class Person:
class Person {
public:
int Age;
int ID;
};
And I have 2 classes: Adult and Child that inherit Person:
class Child : Person{
public:
Child();
void print_ms_child(){
cout << "I'm an child";
}
};
class Adult : Person{
public:
Adult();
void print_ms_Adult(){
cout << "I'm an adult";
}
};
I want to declare a Person Object
int main() {
Person my_Person;
my_Person.Age = 10;
my_Person.ID = 013272;
And then use conditions to set its type.
if(my_Person.Age > 18){
my_Person = new Adult(); // this won't work
}
else{
my_Person = new Child(); // this won't work
}
I suppose it it's posible but I don't know the right syntax for doing it (How do I do that?). (Sorry for posting code that won't even compile)
But also, I want to change from Child to Adult in case the Age changes (I'm not even sure that's possible).
my_Person.Age = 21;
my_Person = new Adult(); // this won't work
I would first define your class Person like this instead:
class Person {
int Age;
int ID;
protected:
Person(int age, int id): Age{age}, ID{id} {}
public:
virtual ~Person() = default;
};
That is, Person's constructor is made protected so that a class outside the hierarchy can't create a Person object, and its destructor is made virtual to make it suitable as a base class for a polymorphic type.
Then, both Child and Adult publicly inherit from Person, as you already have them. Their constructors end up calling Person's constructor with the same parametrization their constructors receive:
class Adult: public Person {
public:
Adult(int age, int id): Person(age, id) {}
// ...
};
class Child: public Person {
public:
Child(int age, int id): Person(age, id) {}
// ...
};
Finally, for creating objects that derived from Person, I would create the factory function below:
std::unique_ptr<Person> create_person(int age, int id) {
if (age < 18)
return std::make_unique<Child>(age, id);
else
return std::make_unique<Adult>(age, id);
}
This factory function creates a Child object if the to-create person's age is under 18. Otherwise, it creates an Adult object. This – determining the type of the object to create – is done at run time.
EDIT: You wondered how a Child object could become an Adult object after its age has reached 18 years old.
I would suggest making the state of a Person object immutable so that a fresh new object has to be created every time the age of a person is increased. This way, creating a new object from an existing one will be the only way to grow a Person's age and, at that moment, you will have the control to decide whether to create a Child or Adult object based on the new age.
For doing this, first, qualify the Age data member in Person as const (you can do the same with ID). Then, define the following Person's member function which always creates a new object (with the same ID) resulting from increasing a Person's object Age by one:
std::unique_ptr<Person> Person::increase_age() const {
return create_person(Age + 1, ID);
}
As you see, it delegates the creation of the object to the factory function, create_person(), already explained above. This member function can be called on both Child and Adult objects since it inherits from Person.
You cannot change the type of a variable after its declaration. C++ is a statically typed language. my_person is a Person. You cannot change that.

Two different nodes in one linked list (CPP)

I have a treatment parent class, and two children, inner treatment and outer treatment. I need to create a single linked list that contains both of the children nodes. I'm not allowed to use templates, or built in lists.
The problem I'm facing is the type of the next ptr, the only solution I found is to create a base node parent type, and put the two children inside it, plus a type variable to know which kind of node it is. Something like this:
enum node_type = {inner, outer};
struct treatment_node{
Inner_Treatment t1;
Outer_treatment t2;
struct treatment_node *next;
node_type treatment_type;
}
I'll know which class to access based on the treatment type. Would this work?
As polymorphysm goes, you can use the same wording as in your question, but put a different meaning to the word 'base'. So, you can create a base treatment class and inherit your inner and outer classes from it:
class treatment_node {
treatment_node *next;
public:
virtual std::string getTreatment() = 0;
...
};
now your outer and inner:
class Outer_treatment : public treatment_node {
... members ...
public:
std::string getTreatement() override {...}
};
};
class Inner_treatment : public treatment_node {
... members ...
public:
std::string getTreatement() override {...}
};
Now you can put both on the list of treatement_nodes.

Classes with Arrays using other class objects

I have two completed classes at the moment, the Teacher and Student classes have default definitions.
Right now I am trying to figure out the Classroom and School classes. The Classroom class is supposed to hold a Teacher and an array of 35 Student objects.
The School class is supposed to contain an array of 100 Classroom objects.
How do I do this, I sort of know how to initialize an array in a class but I'm not sure how to achieve this using the objects of another class?
class Teacher
{
private:
string last;
string first;
int gradeLevel;
public:
Teacher();
};
Teacher::Teacher()
{
last = "AAAA";
first = "BBBB";
gradeLevel = 0;
}
class Student
{
private:
string studLast;
string studFirst;
public:
Student();
};
Student::Student()
{
studLast = "AAAA";
studFirst = "BBBB";
}
class Classroom
{
};
class School
{
};
For example:
class Classroom
{
private:
Teacher t; // create a teacher
Student s[35]; // create an array of 35 students
...
};
class School
{
private:
Classroom rooms[100]; // create an array of 100 rooms
...
};
What you want to do here is create a Teacher, just one like you wanted, and then create an array of Student objects, which if you didn't know is done like Student students[35];. Then to the School object which is just an array of Classroom objects. Here is the full code:
class Classroom
{
private:
Teacher teacher;
Student students[35];
public:
Classroom();
};
Classroom::Classroom()
{
;
}
class School
{
private:
Classroom classrooms[100];
public:
School();
};
School::School()
{
;
}
Note: all of the items in the arrays are initialized when you write something like Student students[35];. You can check this by doing cout << this->stduents[12].studLast << endl;

c++ BST and file handling

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;
};

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.