C++ class - Array Of objects - c++

I've to design a ticket booking system for a cinema, which has 50 seats only (5 rows with 10 seats each)
I've been given the Cinema class below, and this should not be modified
class Cinema{
private:
Ticket ticket[50]; // not sure what it is going on
public:
Cinema(); //constructor
double purchaseTicket(int); // ticket ID as parameter, check if it is available, if so update it as unavailable. If not, return 0.
void listAll();
};
And this is the Ticket class
class Ticket{
private:
int ID[50]; //ticket ID (correct to store data in array?)
int price; // ticket price
// have to provide set and get function for ID and price, have no idea even I've googled on this topic
bool available[50]; // availability of ticket
public:
Ticket(); //constructor
bool status(int); // return availability of ticket
void setAvailable(int); //update status of ticket as available
void buy(int); //update status of ticket as unavailable
};
This is the main function (given) which simulates the purchase ticket function
int main(){
Cinema myCinema;
myCinema.listAll(); // available seats print "O", otherwise print "X"
//simulate to purchse ticket 15, 16, 17
double price = 0;
price += myCinema.purchaseTicket(15);
price += myCinema.purchaseTicket(16);
price += myCinema.purchaseTicket(17);
cout <<"\nTotal Price: $" << price << endl << endl;
//print the current status
myCinema.listAll();
return 0;
}
can anyone tell me how to use "Ticket ticket[50];" ? this troubles me a lot and many steps cannot be finished
and tell me also if there are any problems in the Ticket class

Each seat has a ticket. Therefore there are fifty tickets to purchase. It's a slightly strange way of looking at things but I think you can think of 'ticket' as synonymous with 'seat'.
Your ticket class is wrong. Remember a ticket object represents an individual ticket (which stands for an individual seat). Therefore one ticket has one id, and one availability. Therefore the arrays in the ticket class are wrong.
class Ticket{
private:
int ID; //ticket ID
int price; // ticket price
bool available; // availability of ticket
public:
...
};
The setters and getters are trivial
int Ticket::getPrice() const { return price; }
void Ticket::setPrice(int p) { price = p; }
Similar for availability.
Just noticed that Cinema::purchaseTicket returns a double, why I have no idea.

You cannot use ticket array directly, since it is a private member of Cinema. You can only access it using the purchase function mentioned in the class. Since that class should not be modified, this is the only way.
(Note: int array for ID member is wrong, use only int).
However, if you were to modify that class to make Ticket ticket[50] as public,
An example on how to use it is as follows:
myCinema.ticket[0].ID to access the first ticket's ID ( preferably use char array to store ticket ID, else just int: int array is wrong)
access the members u want through the dot operator.

Related

Static class variable initializing to 100 by itself

This is my first question on here, so excuse me if I've formatted everything in a wrong way.
So, to get to the problem - this is s university assignment of mine. The goal is to create a class called Student, which has a few fields, and store the instances in an array of Student objects. One of the tasks is to have a static variable inside the class that keeps track of how many Student instances have been created. To clarify, I have a getData() method that asks the user for the values, and then sets the current object's values to those entered (basically just like a constructor, which makes the constructors obsolete, but they want us to do it that way for some reason). In the getData() function, the static count variable gets raised by 1, as well as in the constructors, and gets decremented in the destructor.
The issue is that for some reason, Student::amount variable sets itself to 100. Every time that i try to access it from the main() function, its 100 plus the amount of students created, so if we have created 2 students, Student::amount will be equal to 102. I've nowhere explicitly set it to that number, which also matches the size of the array, by the way.
I'm still rather new to C++, I've read and watched some material on how OOP works here, but I've barely even scratched the surface.
Sorry again if my question is badly formulated or/and badly formatted, and I hope you can help me with this!
#include <iostream>
#include <string>
using namespace std;
class Date {
...
};
class Student {
// Fields
private:
string name = "";
string PID = "";
int marks[5]{ 0 };
short course = 0;
public:
// Count of all students
static int amount;
// Getters
...
// Setters
...
// Constructors
Student(); // Default one, Student::amount gets raised by 1 there
Student(string name, string PID, int marks[5], short course);
// Destructor
~Student();
// Methods
void getData();
void display(); // Display the information of a student
};
// Array of students
Student students[100];
// Student::Count
int Student::amount; // Initializes with 0 if not explicitly initialized
void Student::getData() {
cin.ignore();
cout << "\nName: "; getline(cin, name);
cout << "PID: "; getline(cin, PID);
cout << "Marks:\n";
for (int i = 0; i < 5; i++)
{
cin >> marks[i];
}
cout << "Course: "; cin >> course;
Student::amount++;
}
Student::Student(string name, string PID, int marks[5], short course) {
this->setName(name);
this->setPID(PID);
this->setMarks(marks);
this->setCourse(course);
Student::amount++;
}
The global declaration Student students[100]; calls the default Student constructor 100 times, before main is reached. According to your comment (you don't supply the constructor implementation), that constructor increases amount by 1.
A solution here is to remove Student::amount and instead use
std::vector<Student> students;
students.size() will give you the number of students in that container. Use push_back to put students into the vector.
A very crude alternative that at least is broadly compliant with the question constraints is to remove the amount increment from the default constructor, and all other places apart from the four argument constructor.

I am getting garbage value while using operator overloading

I have got a question -
Write a c++ program to calculate Gross salary(net salary+DA+TDS) for 4 employees where overload the + operator for getting the total salary obtained by all the 4 employees. Also get the average salary of employees by operator overloading. display all the details of all four employees. Also display who is getting highest salary. Employee salary must be entered by the user at runtime.
#include<iostream>
#include<string>
using namespace std;
class Employee
{
private:
int net_salary, DA, TDA, Gross_salary;
public:
void SetData(int net, int da, int tda, int gross)
{
net_salary=net;
DA=da;
TDA=tda;
Gross_salary=gross;
}
void GetData()
{
cout << "Enter net salary: "<<net_salary;
DA = (15*net_salary)/100; //Declaring the value of DA as 15% and calculating the amount
//on basis of net salary of the employee
TDA = (10*net_salary)/100; //Declaring the value of TDA as 10% and calculating the amount
// of TDA on basis of net salary
Gross_salary = net_salary+DA+TDA;
}
void DisplayData()
{
cout << "Total Gross Salary = "<<Gross_salary;
}
Employee operator +(Employee e)
{
Employee temp;
temp.Gross_salary=Gross_salary+e.Gross_salary;
return temp;
}
};
int main()
{
Employee e1,e2,e3,e4,e5;
e1.GetData();
e2.GetData();
e3.GetData();
e4.GetData();
e5=e1+e2+e3+e4;
e5.DisplayData();
return 0;
}
The trouble comes from the absent initial values for the data members.
// ...
cout << "Enter net salary: " << net_salary;
DA = (15*net_salary)/100;
// ...
Here, in the GetData() member function, that is called after you have created five default initialized objects e1,e2,e3,e4,e5 of Employee type. The net_salary here is of built-in type and is default initialized by the implicitly defined default constructor, hence it has an undefined value. Then you assign this undefined value to the DA and so on in the body of the GetData().
You should not look toward the SetData() as a solution for this, since it should act as a setter method, a method used to modify an already initialized object. You will need to implement constructor(s) for your class, or you can at least supply in-class initializers for the members, like so:
// ...
int net_salary=0, DA=0, TDA=0, Gross_salary=0;
// ...
I can't help but notice that GetData() either has a confusing name or tries to do more than it is intended to do. It does some internal computation, which is ok for a GetSomething function, but it modifies internal data while does some prints.
Also, note the line (in the GetData()):
Enter net salary:
Will be followed by an output, you won't be given a chance to input any data in the GetData(). I assume, you may want to create a constructor that takes input from a user, and then call a function to do all the needed computations.

define book class with member function and store value

Can someone please help me with the below requirement
Class book that that contains attributes BookId, BookName, and Price. It also contain member function to input and show its attributes.
Write another class Writer that contains that contains the attributes of WriterName, Address and NumberofBooks written by him. It contains array of book objects as iys member. The length of array should be 5 to store the data of five books.
It should also contain a member function to input and display its attributes.
I found a solution on google with below code but it appears it is useful for my half requirement.
#include<iostream.h>
#include<stdio.h>
#include<conio.h>
class BOOK
{
int BOOKNO;
char BOOKTITLE[20];
float PRICE;
void TOTAL_COST(int N)
{
float tcost;
tcost=PRICE*N;
cout<<tcost;
}
public:
void INPUT()
{
cout<<"Enter Book Number ";
cin>>BOOKNO;
cout<<"Enter Book Title ";
gets(BOOKTITLE);
cout<<"Enter price per copy ";
cin>>PRICE;
}
void PURCHASE()
{
int n;
cout<<"Enter number of copies to purchase ";
cin>>n;
cout<<"Total cost is ";
TOTAL_COST(n);
}
};
void main()
{
BOOK obj;
obj.INPUT();
obj.PURCHASE();
getch();
}
To contain an instance of an object you declare a member of that type in your class:
class Writer
{
const size_t MAX_BOOKS_WRITTEN = 5U;
Book books_written[MAX_BOOKS_WRITTEN];
};
In the above class, "that contains that contains" an array of books written.

Trying to create a class array in another class

Trying to build a database using classes.
This is just an excerpt of the classes, my main() creates a bunch of students using the class Student. Each student then has an ID and Name that are inputted later. Additionally, each student will have an array of 2 slots which will hold info for their courses they're taking. Those courses are created using the class Course.
What I'm trying to figure out is how can I place the course info (courseID and courseName) into a slot of the student's courses array once I assign them a course (in other words, student A is now in class 1. I want the courseID and courseName of class 1 to be assigned to student A's courses).
I try to use the locations of each course created in the main but that proves difficult trying to output. Is it possible to be in the class Student and have it call a function from class Course? Any help be great. Thanks.
class Course {
protected:
int courseID;
char* courseName;
public:
Course() {
courseID = 0;
courseName = "";
}
void makeID(int id, char* name) {
courseID = id;
courseName = name;
}
int getID() {
return courseID;
}
char* getCourseName() {
return courseName;
}
};
class Student : public Course {
private:
int studentID;
char* studentName;
int classCount;
int courses[2]; //could I change to: Course courses[2]?
char name[30];
int id;
public:
Student() {
studentID = 0;
studentName[30];
classCount = 0;
courses[2];
}
void makeStudent() {
cout << "Input 9 digit student ID: ";
cin >> id;
studentID = id;
cin.ignore();
cout << "Input first and last name of the student: ";
cin.getline(name, 30, '\n');
studentName = name;
return;
}
int getstudentID() {
return studentID;
}
int getclassCount() {
return classCount;
}
char* getstudentName() {
return studentName;
}
void addClass(int course) {
if (classCount == 2) {
cout << "Max amount of courses reached." << endl;
}
else {
courses[classCount] = course;
classCount++;
}
return;
}
int returnClass(int course) { //can't figure out what to do
return courses[course]; //here.
}
};
At very first, you should get a clear image how your data model shall look like.
OK, we have bunch of courses and a bunch of students. Courses and students are totally unrelated (apart from students attending courses) concepts at first, so it won't make any sense one inheriting from the other...
Imagining the scenario does not only cover one single period (school year, semester, trimester, ...), courses might change over time as well as will the students.
So you might have a vector or another data structure storing courses on one hand and students on the other.
Students will attend courses, this can be reflected in two ways:
courses holding lists of all students attending them
students holding lists of all courses they attend
Depending on use case, it might be appropriate to implement both redundantly.
How would you install such a relation ship? Easiest (at a first glance, at least) would be X holding one or more pointers to Y in both scenarios.
class Course
{
std::vector<Student*> participants;
public:
// whatever you need...
};
class Student
{
std::vector<Course*> students;
public:
// whatever you need...
};
As I now use pointers to represent the relation ship, the data structures holding all courses and students must not invalidate these if adding or removing students from! std::vector<X> would do so, so you cannot use it. Alternatives would be std::vector<std::unique_ptr<X>> or std::list<X>. Actually, std::vector<X*> would work as well, but then it would be you who would need to care for deletion, if removing courses or students, so prefer one of the other solutions.
But why did I not use smart pointers for the courses' and students' vectors? We'd be forced to use std::shared_ptr then for, but we won't profit from: If a student leaves our institution, we'd have to eliminate her/him anyway and remove her/him from all courses being attended. So we don't profit from smart pointers in this scenario (can be totally different in other ones). Analogously if a course is cancelled.
So make sure in the destructors the classes that
a course is removed from all students' vectors in its own vector
student is unregistered from all courses in its vector
With these basics, you can get ID, name and other data for a specific course a student attends simply via the pointer in the vector.
If you often seek via a specific information, (e. g. by name), you might have a std::map as well, facilitating the lookup by the specific attribute. You might use such a map for the complete list of courses/students as well, then, though, be aware that pointers are only guaranteed to remain valid in std::map<X, Y>, not in std::unordered_map<X, Y>, so if you intend to use the latter, you'd have to go the way via smart pointer again as with the vector: std::unordered_map<X, std::unique_ptr<Y>>.

Why does this error happen (C++)? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I have a class called SavingsAccount with a method called calculateMonthlyInterest. If I arrange my main method like this, it works just fine, with saver1 having interest of $60 and saver2 having interest of $90:
void main() {
// create two savings account objects, then calculate interest for them
int balance = 200000;
SavingsAccount saver1(balance);
saver1.calculateMonthlyInterest();
balance = 300000;
SavingsAccount saver2(balance);
saver2.calculateMonthlyInterest();
cin.ignore(2); // keeps console from closing
}
However, if I arrange it like this, saver1 and saver2 both have interest of $90, even though that is incorrect for saver1:
void main() {
// create two savings account objects, then calculate interest for them
int balance = 200000;
SavingsAccount saver1(balance);
balance = 300000;
SavingsAccount saver2(balance);
saver1.calculateMonthlyInterest();
saver2.calculateMonthlyInterest();
cin.ignore(2); // keeps console from closing
}
Obviously I can avoid the error by arranging it the first way, but I was just wondering why this is. Either way, shouldn't it pass a different value for the saver1 and saver2 objects, or am I missing something?
Edit: Here's the rest of the program for those who want to see it:
#include <iostream>
using namespace std;
class SavingsAccount {
public:
SavingsAccount(int& initialBalance) : savingsBalance(initialBalance) {}
// perform interest calculation
void calculateMonthlyInterest() {
/*since I am only calculating interest over one year, the time does not need to be
entered into the equation. However, it does need to be divided by 100 in order to
show the amount in dollars instead of cents. The same when showing the initial
balance */
interest = (float) savingsBalance * annualInterestRate / 100;
cout << "The annual interest of an account with $" << (float)savingsBalance / 100 << " in it is $" << interest << endl;
};
void setAnnualInterestRate(float interestRate) {annualInterestRate = interestRate;} // interest constructor
int getBalance() const {return savingsBalance;} // balance contructor
private:
static float annualInterestRate;
int& savingsBalance;
float interest;
};
float SavingsAccount::annualInterestRate = .03; // set interest to 3 percent
Think about it this way. You have a balance. Now do you want it to be the balance to every account there is? or do you want it to have different values for different accounts?
Certainly you want it to change in different accounts. That means different accounts should have different copies of the balance. What you did in the code is declaring it as a reference and passing reference through the constructor. When you accept and assign references, it does not copy the value from one to another, rather it makes both referring to the same object (balance, in this case). Now after you have intialized both, if you change the balance in main, the change will be reflected in both accounts because the savingsBalance they have and the balance inside main are essentially the same objects.
To correct it, change the int &savingsBalance to int savingsBalance, and change SavingsAccount(int& initialBalance) to SavingsAccount(int initialBalance). That will make it accept the values stored in initialBalance.