C++ Using a class from a header within a class - c++

I'm having a bit of trouble with classes used within classes, from header files.
I have a class time in time.h:
#ifndef TIME_H
#define TIME_H
#include <iostream>
using namespace std;
class Time
{
private:
int hour, minute, second;
public:
Time();
~Time();
Time(int h, int m, int s);
int getHour();
int getMinute();
int getSecond();
void setHour(int hour);
void setMinute(int minute);
void setSecond(int second);
Time getTimeFromUser(Time b);
bool validTime(Time a);
void print24Hour(Time a);
void print12Hour(Time b);
};
#endif
Schedule.h
#ifndef SCHEDULE_H
#define SCHEDULE_H
#include <iostream>
#include "time.h"
using namespace std;
class Class
{
private:
string name;
int credits;
bool majorRequirement;
double avgGrade;
string days;
Time startTime;
Time endTime;
public:
Class();
~Class();
Class(string namae, int cred, bool majorReq, double avg, string day);
//Mutate
void setName(string h);
void setCredits(int c);
void setMajorRequirement(bool set);
void setAvgGrade(double g);
void setDays(string d);
void getStartTimeFromUser(Time b);
void getEndTimeFromUser(Time e);
// Access
string getName();
int getCredits();
bool getMajorRequirement();
double getAvgGrade();
string getDays();
Time& getStartTime();
Time& getEndTime();
};
#endif
Schedule.cpp:
Class::Class()
{
string name = "";
int credits = 0;
bool majorRequirement = false;
double avgGrade = 0.0;
string days = "";
}
Time::Time()
{
int hour = 0;
int minute = 0;
int second = 0;
}
Class::Class(string namae, int cred, bool majorReq, double avg, string day)
{
name = namae;
credits = cred;
majorRequirement = majorReq;
avgGrade = avg;
days = day;
}
Time::Time(int h, int m, int s)
{
second = s;
minute = m;
hour = h;
}
Time getTimeFromUser(Time b)
{
string time = "";
string hourS, minuteS, secondS = new string();
getline(cin,time);
hourS = time.substr(0,2);
minuteS = time.substr(3,2);
secondS = time.substr(6,2);
b.hour = atoi(hourS.c_str());
b.minute = atoi(minuteS.c_str());
b.second = atoi(secondS.c_str());
return b;
}
void getStartTimeFromUser(Time b)
{
startTime = getTimeFromUser(b);
}
void getEndTimeFromUser(Time e)
{
endTime = getTimeFromUser(e);
}
Other Mutators and Accessors here.
Main is long. Here is the severely condensed version:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <iomanip>
#include "time.h"
#include "schedule.h"
using namespace std;
int main()
{
// Expecting that variables are properly declared
Class * klass = new Class[classcount];
cout << "Enter the start time for the class (format is HH:MM:SS): ";
klass[i].getStartTimeFromUser(classB);
cout << "Enter the end time for the class (format is HH:MM:SS): ";
klass[i].getEndTimeFromUser(classE);
for(int i = 0; i < classcount; i++)
{
// Data collected via getline and changed through mutators/accessors
// Problems arise when working with Time
klass[i].getStartTime().print24hour();
}
}
I get quite a few "hour, second, minute, etc." are private errors, I'm guessing I'm doing something simple in a rather wrong way. Please help.
I get a lot of this:
time.h:10:7: error: ‘int Time::hour’ is private
schedule.cpp:146:4: error: within this context
time.h:10:13: error: ‘int Time::minute’ is private
schedule.cpp:147:4: error: within this context
time.h:10:21: error: ‘int Time::second’ is private
schedule.cpp:148:4: error: within this context
schedule.cpp: In function ‘void getStartTimeFromUser(Time)’:
schedule.cpp:155:16: error: ‘setStartTime’ was not declared in this scope
schedule.cpp: In function ‘void getEndTimeFromUser(Time)’:
schedule.cpp:160:2: error: ‘endTime’ was not declared in this scope
time.h: In function ‘bool validTime(Time)’:

There are several errors in your code:
I assume class in your main() function represents an array of
Class; but this is illegal, since class is a C++ keyword.
You are trying to access a private member of a Class object
(class[i].startTime). This is illegal again. You would need a
public accessor to that data member:
You are calling a function that does not exist (print24()). If you
intended to call print24hour(), this function takes no parameters.
Putting it all together, you need to do three things:
Add an accessor for startTime in Class:
class Class
{
//...
public:
Time GetStartTime() {return startTime;}
};
Use a legal name for your array and use std::vector or std::array:
std::vector<Class> classArray;
// OR:
std::array<Class, SIZE> classArray;
Call the right methods correctly:
classArray[i].GetStartTime().print24hour();

I you want to access class[i].startTime.print24(getStartTime()) from main you need to make startTimepublic.
If this is good style is a different question.

You are trying to access the private members of a class using the object directly.
Please read about public and private access specifiers here.

class Class
{
private:
Time startTime;
public:
const Time & getStartTime(){
return startTime;
}
};
int main()
{
Class c;
c.getStartTime().print24Hour();
}
You want either that, or make startTime public.
Note the const; if you don't want the returned reference to be const, then make startTime public right now. You may think that making it private improves encapsulation; and yes, it does, as long as you don't provide read-write access to the variable, which happens if you don't mark the member function return type const.
If your printing function isn't marked const, then your const-correctness doesn't exist. If using const reference as return type here, then you have some things to fix.
Related reading: Pseudo-Classes and Quasi-Classes.

Related

C++ Object declaration needs another object as parameter

Object-oriented C++ here.
I'm supposed to code a Microwave object that "heats" a FrozenMeal object.
One method of the Microwave object, called void heatMeal(FrozenMeal), is supposed to take an instance of a FrozenMeal object as a parameter and increase its temperature.
FrozenMeal.h
#include <string>
class FrozenMeal {
public:
FrozenMeal(std::string, int);
void setTemperature(double);
std::string getName() const;
int getVolume() const;
double getCoeffizient() const;
double getTemperature() const;
private:
std::string name;
int volume;
double temperature;
double coeffizient;
};
FrozenMeal.cpp
#include <string>
#include "FrozenMeal.h"
using namespace std;
FrozenMeal::FrozenMeal(string mealName, int mealVolu) {
name = mealName;
volume = mealVolu;
temperature = -18;
coeffizient = 0.24;
}
void FrozenMeal::setTemperature(double mealTemp) { temperature = mealTemp; }
string FrozenMeal::getName() const { return name; }
int FrozenMeal::getVolume() const { return volume; }
double FrozenMeal::getCoeffizient() const { return coeffizient; }
double FrozenMeal::getTemperature() const { return temperature; }
Microwave.h
#include "FrozenMeal.h"
class Microwave {
public:
Microwave();
void morePower();
void lessPower();
void setPeriod(double);
void heatMeal(FrozenMeal); // <----------------------------
int getPower() const;
double getPeriod() const;
private:
int power;
double period;
};
Microwave.cpp
#include "Microwave.h"
using namespace std;
Microwave::Microwave() {}
void Microwave::morePower() { if (power < 1000) power += 200; }
void Microwave::lessPower() { if (power > 200) power -= 200; }
void Microwave::setPeriod(double sessionPeri) { period = sessionPeri; }
void Microwave::heatMeal(FrozenMeal mealInst) {
mealInst.setTemperature(80); //example
}
int Microwave::getPower() const { return power; }
double Microwave::getPeriod() const { return period; }
Now, my problem is that my compiler says that the file FrozenMeal.h apparently redefines the object type of FrozenMeal, even though that should be the job of the FrozenMeal.cpp file, and compiling is unsuccessful.
I tried including FrozenMeal.h to Microwave.cpp but that resulted in even more compiler errors.
I feel like I'm doing something horribly wrong here.
Add include guards to your header files so its contents doesn't get included more than once:
FrozenMeal.h:
#ifndef FROZENMEAL_H_INCLUDED
#define FROZENMEAL_H_INCLUDED
// your code ...
#endif /* FROZENMEAL_H_INCLUDED */
Microwave.h:
#ifndef MICROWAVE_H_INCLUDED
#define MICROWAVE_H_INCLUDED
// your code ...
#endif /* MICROWAVE_H_INCLUDED */
Also, you never initialize int Microwave::power and double Microwave::period so you will read and write garbage values in Microwave::morePower() and Microwave::lessPower()
As suggested in the comments, you want to take the parameter of Microwave::heatMeal() by reference so the function can modify the passed object:
void Microwave::heatMeal(FrozenMeal &mealInst)
// ^

Variable or field declared void C++

I am making a school assignment, but I am getting a strange error. I have tried to google it, but nothing helped.
So I have a file called main.cpp. Within this file I have some includes and code.
This:
#include <iostream>
#include <stdexcept>
#include <string>
using namespace std;
#include "RentalAdministration.h"
#include "Limousine.h"
#include "Sedan.h"
void addTestDataToAdministration(RentalAdministration* administration)
{
string licencePlates[] = {"SD-001", "SD-002", "SD-003", "SD-004", "LM-001", "LM-002"};
for (int i = 0; i < 4; i++)
{
Car* sedan = new Sedan("BMW", "535d", 2012 + i, licencePlates[i], false);
administration->Add(sedan);
}
for (int i = 4; i < 6; i++)
{
Car* limousine = new Limousine("Rolls Roys", "Phantom Extended Wheelbase", 2015, licencePlates[i], true);
administration->Add(limousine);
}
}
int main( void )
{
RentalAdministration administration;
addTestDataToAdministration(&administration);
}
So the compiler tells me that the variable: "RentalAdministration administration" does not exist.
So if we have look in my rentaladministration header. We see this:
#ifndef RENTALADMINISTRATION_H
#define RENTALADMINISTRATION_H
#include <vector>
#include "car.h"
class RentalAdministration
{
private:
std::vector<Car*> Cars;
Car* FindCar(std::string licencePlate);
Car* FindCarWithException(std::string licencePlate);
public:
std::vector<Car*> GetCars() const {return Cars;}
bool Add(Car* car);
bool RentCar(std::string licencePlate);
double ReturnCar(std::string licencePlate, int kilometers);
void CleanCar(std::string licencePlate);
RentalAdministration();
~RentalAdministration();
};
#endif
This is the exact error:
src/main.cpp:18:34: error: variable or field ‘addTestDataToAdministration’ declared void
void addTestDataToAdministration(RentalAdministration* administration)
^
src/main.cpp:18:34: error: ‘RentalAdministration’ was not declared in this scope
src/main.cpp:18:56: error: ‘administration’ was not declared in this scope
void addTestDataToAdministration(RentalAdministration* administration)
Help will be appreciated!
Edit:
I am getting warnings in sublime for the Sedan and Limousine headers. Something that has to do with some static constants. I think it was called a GNU extension. Maybe it has something to do with it.
Even when I comment the call of that function out. I get the same error.
I am calling that function nowhere else.
Some people say that the cause might be in these headers:
#ifndef LIMOUSINE_H
#define LIMOUSINE_H
#include "Car.h"
//c
class Limousine : public Car
{
private:
bool needsCleaning;
bool hasMiniBar;
static const double priceperkm = 2.5;
public:
double Return(int kilometers);
void Clean();
bool GetHasMiniBar() const { return hasMiniBar;}
void SetHasMiniBar(bool value) {hasMiniBar = value;}
Limousine(std::string manufacturer, std::string model, int buildYear, std::string licencePlate, bool hasminiBar);
~Limousine();
};
#endif
2:
#ifndef SEDAN_H
#define SEDAN_H
#include "Car.h"
//c
class Sedan : public Car
{
private:
int lastCleanedAtKm;
bool hasTowBar;
bool needsCleaning;
static const double priceperKm = 0.29;
public:
void Clean();
int GetLastCleanedAtKm() const {return lastCleanedAtKm;}
void SetLastCleanedAtKm(bool value){ lastCleanedAtKm = value;}
bool GetHasTowBar() const {return hasTowBar;}
void SetHasTowBar(bool value) {hasTowBar = value;}
bool GetNeedsCleaning() const {return needsCleaning;}
void SetNeedsCleaning(bool value){needsCleaning = value;}
Sedan(std::string manufacturer, std::string model, int buildYear, std::string licencePlate, bool hastowBar);
~Sedan();
};
#endif
class Limousine : public Car
{
private:
static const double priceperkm = 2.5;
...
}
Remove the static and declare the member simply as const double, example:
class Limousine : public Car
{
private:
const double priceperkm = 2.5;
...
}
The error message ‘RentalAdministration’ was not declared in this scope indicates that the right header file for RentalAdministration was not included. Check the file names to make sure class declaration for RentalAdministration is in the right file.
Restarting the terminal has somehow solved this error. I got another error this time, which I solved already. I missed the destructor. It stood in the header file, but not in the cpp file.
Buggy terminals...

Cannot display file(related to classes)

So I am trying to read in a file using private class variables. I am unsure how to display the file. There might be another way to do this, but this is what I could think of. Note, its my first project using classes and private and public/private members. Was I on the right path atleast? I keep getting an error for the int main function. How can I fix it?
This is my main:
#include "Record.h"
#include <sstream>
int main ()
{
Record employee;
ifstream myFile;
myFile.open("Project 3.dat");
string str;
int i=0;
if (myFile.is_open())
{
while (getline(myFile, str))
{
istringstream ss(str);
ss >> employee.get_name(str) >> employee.get_id(stoi(str)) >>
employee.get_rate(stoi(str)) >> employee.get_hoursWorked(stoi(str));
}
}
return 0;
}
This is my header:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Record
{
private:
string name;
int id;
double rate;
double hours;
public:
Record();
Record (string n, int empid, double hourlyRate, double hoursWorked);
// constructor
void read_data_from_file();
double calculate_wage();
void print_data();
/* ASETTERS AND GETTERS */
void set_name (string n);
string get_name();
void set_id (int empid);
int get_id();
void set_rate (double hourlyRate);
double get_rate();
void set_hoursWorked(double hoursWorked);
double get_hoursWorked();
/* END OF SETTERS AND GETTERS */
};
This is my cpp
#include "Record.h"
Record::Record():name(), id(0), rate(0), hours(0) {} //default constructor
must be implemented first
Record::Record(string n, int empid, double hourlyRate, double hoursWorked)
{
name = n;
empid = id;
hourlyRate = rate;
hoursWorked = hours;
}
//
void Record::set_name(string n)
{
name = n;
}
string Record::get_name()
{
return name;
}
//
void Record::set_id(int empid)
{
id = empid;
}
int Record::get_id()
{
return id;
}
//
void Record::set_rate(double hourlyRate)
{
rate = hourlyRate;
}
double Record::get_rate()
{
return rate;
}
//
void Record::set_hoursWorked(double hoursWorked)
{
hours = hoursWorked;
}
double Record::get_hoursWorked()
{
return hours;
}
//
double Record::calculate_wage()
{
return (rate * hours);
}
There are some issues with your code that I can see. most of your problems aren't related to your question (I mean using a class or private/public members). you have more basic misunderstandings. So here's some explanation that might help you:
1- Using functions : You have some troubles using your defined functions, A function can have multiple input parameters and one return value. basically it's like this return_type function_name(parameter_type param1, ...). it means that if you call this function you need to pass param1,... and expect your function operation and then have a return value of return_type. You defined some set and get functions. if you want to set something you should call set function and pass your desired value to it and it will copy your value to your defined member data, after that you can call get function to retrieve that value. So when you call get function with parameter it will raise error. Here you want to call set function.
2- Using stoi : As you can see you are getting error on using stoi function too, this is a function for converting string to integer, The thing that you missed here is that this function declared in std namespace. If you want to use it you need to use it like this std::stoi(str). one other thing, using namespace std is a bad practice.
3- Design matters : In OOP design, a class must have a purpose and an actual job to do. It might be an interface to abstract class but a bunch of set and get functions will not fulfill the need to create a class. Here if your class is going to do file operations, it's OK, but as far as you shared your code it's just some set and get functions.

How to pass a private member variable to another class?

Based on my Snack.cpp, Snack header file, MiniVend header file & miniVend.cpp file, I am trying to move my Snack private member - price into my MiniVend.cpp file to generate the amount * price to return a total value of items in my machine. How do I access the price from another class?
Portion of my miniVend.cpp file
double miniVend::valueOfSnacks()
{
return //// I don't know how to get snacks price in here? I need to access snacks & getSnackPrice.
}
miniVend header
#ifndef MINIVEND
#define MINIVEND
#include <string>
#include "VendSlot.h"
#include "Snack.h"
using std::string;
class miniVend
{
public:
miniVend(VendSlot, VendSlot, VendSlot, VendSlot, double); //constructor
int numEmptySlots();
double valueOfSnacks();
//void buySnack(int);
double getMoney();
~miniVend(); //desructor
private:
VendSlot vendslot1; //declare all the vending slots.
VendSlot vendslot2; //declare all the vending slots.
VendSlot vendslot3; //declare all the vending slots.
VendSlot vendslot4; //declare all the vending slots.
double moneyInMachine; //money in the machine
};
#endif // !MINIVEND
Snack.cpp
#include "Snack.h"
#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;
}
Snack.h file
#ifndef SNACK_CPP
#define SNACK_CPP
#include <string>
using std::string;
class Snack
{
private:
string nameOfSnack;
double snackPrice;
int numOfCalories;
public:
Snack(); //default constructor
Snack(string name, double price, int cals); //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
Assuming getSnackPrice() is public, and Snack.h does exist, you should just be able to call
snackObject.getSnackPrice() * ammount
what you need is friend keyword. Define the
friend class className;
I don't really understand why you don't just implement get()? Accessing private data is really bad. You are breaking the encapsulation. But if you really want to know (i.e. you should NOT do it, it is really BAD), then you just return a reference to a private data as shown below
#include <iostream>
class A
{
public:
A(int a) : x(a) {}
int &getPrivateDataBAD() { return x; }
void print() { std::cout << x << std::endl; }
private:
int x;
};
class B
{
public:
void print(int &s) { std::cout << s << std::endl; }
};
int main()
{
A obj(2);
B bObj;
bObj.print( obj.getPrivateDataBAD() );
return 0;
}

Calling correct virtual methods

Here is my code:
#include <iostream>
#include <string>
using namespace std;
class Sport{
protected:
string name;
double hours;
virtual double returnCalories()=0;
public:
Sport():name("Not defined"),hours(0.0){}
Sport(string n, double c):name(n),hours(c){}
virtual ~Sport(){}
void setName(string x){
name=x;
}
void setTime(double x){
hours=x;
}
};
class Running:public Sport{
public:
static const int CALORIES = 950;
Running(){}
~Running(){}
double returnCalories(){
return hours*CALORIES;
}
};
class Activity{
public:
Sport* one;
Activity(){}
Activity(string n,double time){
one->setName(n);
one->setTime(time);
}
~Activity(){}
};
class Diary{
private:
Activity list_activity[10];
int counter_activity;
public:
Diary():counter_activity(0){}
~Diary(){}
void addActivity(Activity x){
// add activities
}
double sumCalories(){
for(int i=0;i<10;i++){
if(list_activity[i].one->getName()=="Running"){
// I want to call returnCalories() of class Running
}
}
}
};
int main() {
Activity test("Running",3.2);
Diary test2;
test2.addActivity(test);
return 0;
}
Now I have a question:
How is it possible to call returnCalories() of class Running where I want to ? ( it's commented in the code )
Is this even possible, or should I change my logic somehow ?
It's crashing because you have not initialized Sport *one; and you're attempting to call methods on a null pointer. You need to first create a Running object within the Activity constructor using the "new" operator like so:
one = new Running(n, time);
Create an overloaded constructor in your "Running" class that takes the appropriate arguments as well, so that you can initialize your variable as shown above.