c++ how do you implement a has relationship? - c++

for example:
i got great reservations:
the class has memeber the start/end date and a function that gives me the date.
class reservation{
private:
datetime start;
datetime end;
public:
reservation(stardatetime, enddatetime): start(stardatetime), end(enddatetime)
{
}
std::list<std::string> get_reservation()
{
for example: return start;
}
};
and i have a class conference room, which can be booked from one time to another.
class room{
private:
int room_ID;
public:
room(int id):room_ID(id)
{
}
void get_room(){
return room_id;
}
}
that means every room has several reservations.
how can i access through a room id via the reservation?
if i search for room id 1, the reservation of the room will also be displayed.
Thanks.

Here's your problem statement: every room has many reservations, and every reservation has a reference to a single room. Based on this, I would write it as follows (you may add your stuff inside those classes).
#include <iostream>
#include <vector>
using namespace std;
class Room; //forward declaration
class Reservation {
private:
Room* room;
public:
Reservation(Room* roomPtr) {
room = roomPtr;
}
};
class Room {
vector<Reservation> reservations;
};
int main(){
Room room[10]; //an array of 10 rooms with no reservations (calls def.constructor of each Room)
Reservation r1(&room[0]); //reservation object r1 reserving room[0]
Reservation r2(&room[1]); //reservation object r2 reserving room[1]
// ...more stuff goes here
}

Related

I have problem with least privilege principle. incrementing a member when an object is created

I want to keep track of the number of students in my system so, My idea was to make a static datamember in the "StudentController" class called "_numOfStudents" and increment it with the Student's constructor but it didn't work so, I moved it into the "Student" class and made that when a Student object is created the number increment by the help of the constructor. The problem is: isn't it not the Student class's business to know how many students are there thus breaking the principle of least privilege. what can I do better to keep track of the student objects' count.
Student(string firstName, string lastName, int age,vector<float>&subjects)//Student conctructor
{
SetFirstName(firstName);
setLastName(lastName);
SetAge(age);
SetMarks(subjects);
this->m_id++;
StudentController::_numberOfStudents++;
}
class StudentController//this is where i declared the static data member
{
private:
list<Student> _students;
public:
static int _numberOfStudents;
StudentController() {};
StudentController(list<Student>& st) :_students(st) {};
}
}
};
int StudentController::_numberOfStudents = 0;
When you try to do StudentController::_numberOfStudents++; in the constructor, the StudentController class is not yet defined, therefore the compiler doesn't know about that class and its static member.
Maybe keeping track of the students shouldn't be the role of the Student class itself. Instead it should be the role of a separate Classroom object:
struct Student;
struct Classroom {
void add(Student&) {
m_count++;
}
size_t count() const { return m_count; }
private:
size_t m_count{0};
};
struct Student {
Student(Classroom& classroom) {
classroom.add(*this);
}
};
int main()
{
Classroom classroom;
Student alice{classroom};
Student bob{classroom};
assert(classroom.count() == 2);
}

Cannot inherit data from parent class to child class in C++

I am trying to inherit data from two parent classes of Employee and Student to a child class of Manager.I have created set and get functions of each class and i have created a show function in child class which will also show data of both parent classes.But when i make objects and call functions of set values and then show data, only the data of child class is shown.
Can anyone tell my why is that and how do i solve it? Thanks for any help.
Code is below:
class Employee{
protected:
string name;
int number;
public:
Employee(){
name = "";
number = 0;
}
void set_name(string a){
name = a;
}
void set_number(int a){
number = a;
}
string get_name(){
return name;
}
int get_number(){
return number;
}
};
class Student{
protected:
string school;
string degree;
public:
Student(){
school = "";
degree = "";
}
void set_school(string a){
school = a;
}
void set_degree(string a){
degree = a;
}
string get_school(){
return school;
}
string get_degree(){
return degree;
}
};
class Manager:protected Employee, protected Student{
protected:
string title;
int dues;
public:
Manager(){
title = "";
dues = 0;
}
void set_title(string a){
title = a;
}
void set_dues(int a){
dues = a;
}
string get_title(){
return title;
}
int get_dues(){
return dues;
}
void show_data(){
cout << Employee::get_name();
cout << Employee::get_number() << endl;
cout << Student::get_school() << endl;
cout << Student::get_degree() << endl;
cout << get_title() << endl;
cout << get_dues() << endl;
}
};
int main(){
Employee emp;
Student stu;
Manager man;
emp.set_name("Fahad");
emp.set_number(10);
stu.set_school("COMSAT");
stu.set_degree("BSCS");
man.set_title("Manager Title");
man.set_dues(100);
man.show_data();
return 1;
}
You have 3 different objects, each contains its own data!
For example, your manager class contains all attributes from manager, employee and student. In your main function:
Employee emp;
Student stu;
Manager man;
emp.set_name("Fahad");
emp.set_number(10);
stu.set_school("COMSAT");
stu.set_degree("BSCS");
man.set_title("Manager Title");
man.set_dues(100);
man.show_data();
you only set some of the attributes of your objects. For manager, you only set title and dues. If you want to set also the name, you have to do it!
BTW: there is no need to use Student::get_school() to access the members of parent classes if you have not used the same attribute name multiple times or inherit multiple times from the same class.
I believe you want to do the following:
class Manager:public Employee, public Student{ ... };
int main(){
Manager man;
man.set_name("Fahad");
man.set_number(10);
man.set_school("COMSAT");
man.set_degree("BSCS");
man.set_title("Manager Title");
man.set_dues(100);
man.show_data();
return 1;
}
If you change to public for deriving from your parent classes, you can directly access the getter/setter functions from the object as you can see. As you have already getter and setter functions, it is a good idea to make the member vars now private.
BTW: The return value of main is typically 0 to tell that there is no error. If you want to return with "no error", you can simply omit the return statement. main() will than return 0 by default.
The following lines create three objects.
Employee emp;
Student stu;
Manager man;
The emp object is not related to the Employee sub-object of man and the stu object is not related to the Student sub-object of man.
The lines
emp.set_name("Fahad");
emp.set_number(10);
change the state of the independent emp object. They don't change the state of the Employee sub-object of man.
You need to use:
int main(){
// Employee emp; Not needed
// Student stu; Not needed
Manager man;
man.set_name("Fahad");
man.set_number(10);
man.set_school("COMSAT");
man.set_degree("BSCS");
man.set_title("Manager Title");
man.set_dues(100);
man.show_data();
return 1;
}
to see the values set on the same object. However, to do that you need to change the inheritances of Manager. Use
class Manager : public Employee, public Student {
...
};
Your code does not work as expected because:
You allocate separate objects/instances of each Employee, Student and Manager, e.g. emp, stud and man and set the data on each separate instance (for example, the emp.set_name() will only affect the emp object, not the man object).
You print the data member of the man object which does not include the data set in emp and man.
I do not know what the ideas behind your code design is, I do recommend to leave out multiple inheritance as it quickly leads to unmaintainable code. But to get your example code to work, do the following:
Delete the allocation of emp and stu;
change the emp and stu variable names in the setter calls to man.
Change protected to public in the Manager declaration where Manager extends Student and Employee.
class Manager:public Employee, public Student{
int main(){
Manager man;
man.set_name("Fahad");
man.set_number(10);
man.set_school("COMSAT");
man.set_degree("BSCS");
man.set_title("Manager Title");
man.set_dues(100);
man.show_data();
return 1;
}
And you will get the output I assume you expect.

How to access struct variables within a class, inside a different class?

I have multiple files for each class. I'm trying to use data from a struct (inside the first class) and use it in the second class.
I've tried putting the struct in its own file, but this felt a bit unnecessary. I've tried a few different ways of coding it out, such as declaring the struct in main and also declaring the struct in the other class.
// class 1
class Shop
{
public:
struct Products
{
int price;
int quantity;
};
void SetProductValue();
private:
float register_total;
};
// class 2:
class Consumer
{
public:
Shop Products;
int total_customers;
bool buy_product(); // <--
for this?
private:
string consumer_name;
float Consumer_balance;
};
What does the function description look like for void buy_product()?
bool Consumer::buy_product();
{
if (consumer_balance < Products.price) return false;
if (consumer_balance >= Products.price) return true;
}
This is one of several ways I've tried, and I get errors for trying to do Products.price
struct Products { ... }; declares a type, not a product instance.
In order to have an actual product in your class, you have to declare a member variable:
class Shop
{
public:
struct Product // no need for "s"
{
int price;
int quantity;
};
void SetProductValue();
private:
// either:
Product product; // <--- HERE
// or, if your shop has multiple products:
std::vector<Product> products;
float register_total;
};
In order to access one specific product (which one?), your Shop class has to expose some accessor functions. An option is to select a product by name:
Product Shop::GetProductByName(const std::string& name) const
{
// find right product _instance_ here
}

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++ Practice Vehicle Program Issues - Beginner Programming

I have made a little snippet of what my project is essentially based on - except much bigger. I am having a hard to grasping this particular concept. I need to make a car class which inherits the vehicle class and then there must be separate classes such as window, door, engine etc... I need to access those classes through the car class to adjust its "properties"
#include <iostream>
using namespace std;
class Vehicle
{
virtual void print() = 0;
};
class Car : public Vehicle
{
virtual void print();
Wheel tires[4];
};
class Wheel
{
public:
int pressure = 0;
int inflate(int psi)
{
pressure = pressure + psi;
}
};
int main()
{
//What would I have to put here or anywhere else to increase the pressure of a car object's FIRST tire's pressure - Car car1; car1.tires[0].inflate(10); (this doesn't seem to work)
}
#include <iostream>
#include <vector>
using namespace std;
class Vehicle
{
virtual void print() = 0;
};
class Car : public Vehicle
{
virtual void print();
Car(Wheel wheel[4])
{
}
};
class Wheel
{
public:
int pressure = 0;
int inflate(int psi)
{
pressure = pressure + psi;
}
};
int main()
{
Car car1(Wheel wheel[4]);
//I still don't know what I could add here that would inflate the first tire
}
The reason it doesn't work is that default access in a class is private (as opposed to structs, where it is public). With
class Vehicle
{
public:
virtual void print() = 0;
};
// Note that class Wheel has to be defined before class Car, or
// the compiler will complain that class Wheel is unknown here.
class Car : public Vehicle
{
public:
virtual void print();
Wheel tires[4];
};
it should be possible to write
int main() {
Car c;
c.tires[0].inflate(10);
}
Whether it is a good idea to have public data members is another question (it is not a good idea).
Would this work?
class Window
{
//...
};
class Car
: public Vehicle
{
std::vector<Windows> car_windows(5);
};
This is showing that a Car is-a Vehicle that contains 5 Windows.
This should be applied similarly for doors, engine, etc.
Wheel tires[4] will not create any Wheel objects, but just an array. That is why accessing it will not give you anything.
You need to have a Car constructor where you create the wheels of the car.
Also, print is a virtual pure function in Vehicle, so you need to implement it somewhere. Can have print() {}; or similar in your header file.
Or you can just use it to test/debug.
I am assuming you have working constructors.
Try something like this instead:
car1->tires[0]->inflate(10);