Creating a class and using a constructor in C++ (assignment) - c++

For an assignment, I have to create a movie class that contains the name of the movie, the MPAA rating, the number of people that rated it from 1 to 5, find the accumulated value for each of the ratings and the average value.
I'm mainly having trouble with the constructor and the class. I'm trying to make it take an string (And I got that part somewhat right). I'm getting a few errors on line 77 and line 83. I am also stuck since I don't know what steps I should take next. I will appreciate any help possible.
Here is what I got so far:
#include "stdafx.h"
#include <iostream>
#include <string.h>
#include <string>
// Required headers
using namespace std;
//Class movie starts
class Movie {
public:
void SetMovieName(string moviename);
// Function to set the name of the movie
// moviename = movie; later on
string GetMPAAR();
//function to return the MPAA rating
int amountofratingsof1() const;
//function to return the number of people that rated the movie as a 1
int amountofratingsof2() const;
//function to return the number of people that rated the movie as a 2
int amountofratingsof3() const;
//function to return the number of people that rated the movie as a 3
int amountofratingsof4() const;
//function to return the number of people that rated the movie as a 4
int amountofratingsof5() const;
//function to return the number of people that rated the movie as a 5
int average() const;
//function to return the average value of all ratings
std::string Movies(string moviename = "Gavecube: The Movie");
//constructor to set the movie
private:
string Movie; //variable to store the name of the movie
int peoplethatrated1; // variable to store the number of people that rated 1
int peoplethatrated2; // variable to store the number of people that rated 2
int peoplethatrated3; // variable to store the number of people that rated 3
int peoplethatrated4; // variable to store the number of people that rated 4
int peoplethatrated5; // variable to store the number of people that rated 5
};
//implementation file:
void Movie::SetMovieName(const string moviename) {
//function below checks if it is a string or not
if (!cin) {
cout << "Not a valid input. Please restart." << endl;
}
}
int Movie::amountofratingsof1()const {
}
int Movie::amountofratingsof2()const {
}
int Movie::amountofratingsof3()const {
}
int Movie::amountofratingsof4()const {
}
int Movie::amountofratingsof5()const {
}
//constructor
std::string Movie(string moviename) {
SetMovieName(moviesname)
}
int main()
{
Movie Movies("Hello");
return 0;
}
Thank you.

For constructors, they aren't like a normal function. They have no return type, not even void. Within the constructor, if you can use member initiation, you should. Here is a pretty good explanation of constructors if you go down to the Constructors section. In general it should look like:
ClassName (parameter par1, ...) : mem1(par1), ...{}
where mem1 is the data member corresponding to par1. Further down in the link is the member initiation section that covers how to do that. Once you get the constructor setup, you should finish with your member function definitions in whatever order you want then test and debug like you would any other program. Test edge cases and invalid numbers if you need to do error-checking.

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.

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.

Wrong values being passed to constructor in C++

I've been searching everywhere but I can't find a solution, though it's probably a simple one since I'm just starting out. Basically, I'm trying to pass in two values through a constructor, but the values I'm passing in aren't correct either when running or debugging.
Transaction.h
#include <string>
class Transaction {
private:
int amount;
std::string type;
public:
Transaction(int amt, std::string kind);
std::string Report() const;
// ...irrelevant code...
};
Transaction.cpp
#include "Transaction.h"
using namespace std;
Transaction::Transaction(int amt, std::string kind) { };
string Transaction::Report() const {
string report;
report += " ";
report += type; // supposed to concat "Deposit" to string
report += " ";
report += to_string(amount); // supposed to concat amount to string
return report;
// This doesn't return the word "Deposit", nor does
// it return the correct amount. I don't think that
// this is adding "Deposit" to 50, because the values
// change every time I run the program.
}
Parameters.cpp
#include "Transaction.h"
#include <iostream>
using namespace std;
// ...irrelevant code...
int main() {
int money = 50;
cout << "Depositing $" << money << endl;
Transaction deposit(money, "Deposit");
// For some reason, this doesn't pass in int money.
cout << "Original: " << deposit.Report() << endl;
// And this cout prints some large value instead of 50.
// ...irrelevant code...
}
No matter what I do, the value changes. Some output I get:
Depositing $50
Original: 13961048
After pass by value: 13961048
After pass by reference: 27922096
Depositing $50
Original: 11208536
After pass by value: 11208536
After pass by reference: 22417072
Depositing $50
Original: 14092120
After pass by value: 14092120
After pass by reference: 28184240
Any help to point me in the right direction (or just a straight answer) would be great!
The values are being passed to the constructor, alright. The problem is just that you're not doing anything with them!
Look at the implementation for the constructor:
Transaction::Transaction(int amt, std::string kind) { };
This doesn't do anything. In particular, it doesn't save (store) the values of the parameters that were passed.
You probably want this:
Transaction::Transaction(int amt, std::string kind)
: amount(amt)
, type(kind)
{ }
The weird colon syntax is called a member initialization list, and does just what it sounds like.
Note that you should have been able to see this in the debugger. What you'd do is set a breakpoint on the definition of the constructor, and then check to see what the values of the parameters were. You'd see that they were being passed correctly (and that the values were not "wrong"). Then you'd have to figure out why they weren't getting saved, and you could have seen that pretty easily by single-stepping through the code from that point forward.
You don't pass the copy the value of the arguments in the class variables
here the correct contructor code :
Transaction::Transaction(int amt, std::string kind) {
this->amount=amt; //copy the value of amt to Transaction.amount
this->type=kind; //copy the value of kind to Transaction.kind
};

C++ Vending Machine program with classes c++

I am trying to build a vending machine program with 3 different classes but I am stuck on the second portion of it. Basically the first class is the snack class, which takes 3 parameters (calories, name and price.) However, the second class VendSlot, should have two members, a snack (which I presume to be the object from the first files) and the quantity of snacks. I am really struggling to understand how to process the snack object within the second class though. How exactly do I pass the first snack object into my VendSlot class so that I can increase/decrease the amount in my storage in VendSlot and then let the user buy it when I reach the third item? I can't use pointers yet but can pass by reference and I am wondering if this is an effective way? The third class will be a vending machine that will have vendSlots and will take money to buy the items. Thank you for the help and let me know if you need clarification on the project!
This is my Snack header file
#ifndef SNACK_CPP
#include <string>
using std::string;
class Snack
{
private:
string nameOfSnack;
double snackPrice;
int numOfCalories;
public:
Snack(); //default constructor
Snack(string, double, int); //overload constructor
~Snack(); //destructor
//Accessor functions
string getNameOfSnack(); //returns name of snack
double getSnackPrice(); //returns the price of the snack
int getNumOfCalories(); //returns number of calories of snack
};
#endif // !SNACK_CPP
This is my snack.cpp file with constructors
#include "Snack.hpp"
#include <iostream>
#include <string>
using std::endl;
using std::string;
using std::cout;
using std::cin;
Snack::Snack() //default constructor
{
nameOfSnack = "bottled water";
snackPrice = 1.75;
numOfCalories = 0;
}
Snack::Snack(string name, double price, int cals)
{
nameOfSnack = name;
snackPrice = price;
numOfCalories = cals;
}
Snack::~Snack()
{
}
string Snack::getNameOfSnack()
{
return nameOfSnack;
}
double Snack::getSnackPrice()
{
return snackPrice;
}
int Snack::getNumOfCalories()
{
return numOfCalories;
}
Here is my VendSlot header file
#ifndef VENDSLOT_CPP
#include "Snack.h"
#include <string>
class VendSlot
{
public:
VendSlot(); //default constructor
VendSlot(string, double); //overload constructor
string getSnack(); //get snack name
int getAmount(); //get amount of snacks available
void decrementAmount(int); //function to decrease storage in vending machine by 1.
Snack snack; //passes snack object? I am confused what this should be.
~VendSlot(); //destructor
private:
double numOfSnacks; // number of snacks
};
#endif // !VENDSLOT_CPP
And here is my VendSlot.cpp file which I am struggling with
#include "VendSlot.h"
#include "Snack.h"
#include <iostream>
#include <string>
using std::cout;
using std::cin;
using std::endl;
using std::string;
VendSlot::VendSlot()
{
snack;
numOfSnacks = 5;
}
VendSlot::VendSlot(string Snack, double Quantity)
{
snack = Snack;
numOfSnacks = Quantity;
}
int VendSlot::getAmount()
{
return numOfSnacks;
}
string VendSlot::getSnack()
{
return snack;
}
VendSlot::~VendSlot()
{
}
I'm not sure if this is the point of your program or assignment. I'm answering your question of how does the Snack class get its constructor params when it is contained within VendSlot class.
The members contained in another class get their constructor parameters from the initialization list.
Here is an example for your case of how it could be done:
Snack::Snack(string name, double price, int cals) :
nameOfSnack(name),
snackPrice(price),
numOfCalories(cals)
{
}
VendSlot::VendSlot(Snack& snack, int quantity) :
snack(snack),
numOfSnacks(quantity)
{
}
Also, note using a reference is what would normally be used when passing in an entire class or struct. This also means the default Snack copy constructor provided by the compiler will be used unless you implement one yourself. If the class only has simple native types it should work, but to be safe you should implement it yourself.
The member quantity would seem to be best be an int type as you wouldn't have fractions of a snack being sold.
Here's the assignment operator and copy constructor defined as you'll need it.
Snack& Snack::operator=(const Snack& snack)
{
this->nameOfSnack = snack.name;
this->snackPrice = snack.price;
this->numOfCalories = snack.cals;
}
Snack::Snack(const Snack& snack)
{
*this = snack;
}
When you work with classes in C++, imagine them as variables that contain variables. So use them the same way as you use variables.
When you call an instance of a class (or "declare the variables") the constructor is called. There are two ways on doing this. With or without parameters:
Snack A("Chocolate", 12.5, 199);//This will call the constructor with parameters
Snack B;//This will call the constructor without parameters
So now we have two objects of the same class. To use the memebers of the objects we just use a period.
cout << A.getNameOfSnack() << endl;//Output: Chocolate
cout << B.getNameOfSnack() << endl;//Output: bottled water
Also, keep in mind that we can access to the public members only.
Moving on, creating an instace of a class as a member of other class is not different.
class VendSlot {
public:
Snack snack;
int numOfSnacks;
VendSlot();
VendSlot(string, double);
~VendSlot();
};
VendSlot::VendSlot() {
snack = Snack();//Call the constructor to create the object
numOfSnacks = 5;
}
VendSlot::VendSlot(string nameSnack, double Quantity) {//Notice that I changed the name of the first parameter
snack = Snack(nameSnack, 0, 0);//Call the constructor to create the object
numOfSnacks = Quantity;
}
First, you need to be sure that you are not using the name of the class as the name of a variable (that will give you errors, so be careful with that). Now, since the only data you recive in the VendSlot constructor is the name of the snack, there is no more information to send as parameter to the constructor of Snack. You can either add more parameters on the VendSlot constructor or put default values.
Since the variables nameOfSnack, snackPrice and numOfCalories are private members of their class we can't change their values from outside the class Snack.
Within the class VendSlot (or where you create the instance of the class) you can only call the functions getNameOfSnack, getSnackPrice and getNumOfCalories, which are public members of Snack.
So, implying that the function VendSlot::getSnack returns the name of the snack, the function will be as following.
string VendSlot::getSnack() {
return snack.getNameOfSnack();
}
I hope this answers your question.

Not understanding what is being asked and how to type them?

I am having trouble understanding some parts of the question for this program and would like to know why and how to type the program. Here are the parts I'm unable to understand:
The third member variable is a pointer to a double, pquiz. This will be used to dynamically allocate an array which will hold a student's quiz grades.
(Did I do this correctly?)
The fourth member variable is a double holding the average value of the quiz grades.
The class should have a one parameter constructor which accepts an int and will dynamically allocate the array of double quiz grades. Or the class can >have a two parameter constructor which accepts both a string and an int.
The int is the number of quiz grades
The constructor uses the new operator to allocate memory for the array of quiz grades.
If there are two parameters, the string is the student's name.
The class needs the usual mutator, accessor functions and a destructor function.
The class has an additional function, average(), which calculates the average of all the quiz grades held in the array pointed to by pquiz. It returns the double average value.
I'm suppose to print a students name, number of tests the student took, and the average. Here is my program so far:
#include <iostream>
#include <string>
using namespace std;
class TestScore{
private:
string name;
int grades;
double *pquiz;
double average;
public:
TestScore();
void setName(string);
void setGrades(int);
void setAverage(double);
string getName();
int getGrades();
double getPquiz();
double getAverage();
};
TestScore::TestScore()
{
name="?";
grades=0;
pquiz=0;
average=0;
}
void TestScore::setName(string name1)
{
name=name1;
getline(cin,name1);
}
void TestScore::setGrades(int grades1)
{
grades=grades1;
}
void TestScore::setAverage(double average1)
{
average=average1;
}
string TestScore::getName()
{
return name;
}
int TestScore::getGrades()
{
return grades;
}
double TestScore::getAverage()
{
return average;
}
int main()
{
TestScore exam;
TestScore *ts=&exam;
string name;
int grade;
double *pquiz;
double average;
double total=0.0;
int count;
cout<<"Enter student name: ";
exam.setName(name);
cout<<"How many quizzes are there? ";
exam.setGrades(grade);
cin>>grade;
pquiz=new double[grade];
for(count=0; count<grade; count++)
{
cout<<"Quiz "<<(count+1)<<": ";
cin>>pquiz[count];
}
for(count=0; count<grade; count++)
{
total+=pquiz[count];
}
average=total/grade;
cout<<exam.getName()<<" has an average of "<<average<<endl;
delete [] pquiz;
pquiz=0;
return 0;
}
If I understand correctly member grades holds the length of the array pointed to by member pquiz. Whenever grades is set pquiz must also reflect new change (old array should be deleted, new one should be created). In constructor must only create the array. In setGrades() must delete old and create new.
Because member pquiz is controlled (or owned) by the class TestScore it's only logical that it should be deleted when object TestScore is deleted (or in our lingo "when it goes out scope"). This is done in class destructor, which you should add to the class.
According to text there should be one more member function, average(), that calculates the average and stores the value in member average. This member should be renamed, for the sake of your sanity.