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;
}
Related
I am trying to compile this C++ code unfortunately, I failed to compile the code below. Can you help me by explaining why I am getting this error ?
#include <iostream>
#include <cstring>
using namespace std;
class student
{
private:
char name[10];
int id;
int fee;
public:
student(char name[10],int id)
{
strcpy(this->name,name); //string copy
this->id=id;
fee=0;
}
student(char name[10],int id,int fee)
{
student::student(name,id); //calling a constructor of one class
// within a constructor of same class
this->fee=fee;
}
void show() //print function
{
cout<<"Name:"<<name<<endl;
cout<<"id:"<<id<<endl;
cout<<"fee:"<<fee<<endl<<endl;
}
};
int main()
{
student s1("DAVID",123);
student s2("WILLIAM",124,5000);
s1.show();
s2.show();
return 0;
}
Below is the error GCC is complaining about.:
main.cpp|20|error: cannot call constructor 'student::student' directly [-fpermissive]|
As rightly suggested by #sweenish, You must do the constructor delegation in the initialization section. Something like this:
#include <iostream>
#include <cstring>
using namespace std;
class student
{
private:
char name[10];
int id;
int fee;
public:
student(char name[10],int id)
{
strcpy(this->name,name); //string copy
this->id=id;
fee=0;
}
student(char name[10],int id,int fee): student(name, id) // constructor delegation
{
this->fee=fee;
}
void show() //print function
{
cout<<"Name:"<<name<<endl;
cout<<"id:"<<id<<endl;
cout<<"fee:"<<fee<<endl<<endl;
}
};
int main()
{
student s1("DAVID",123);
student s2("WILLIAM",124,5000);
s1.show();
s2.show();
return 0;
}
Also, an advice for you. You may define the more specialized constructor and delegate the responsibility of less specialized constructors to more specialized ones.
#include <iostream>
#include <cstring>
using namespace std;
class student
{
private:
char name[10];
int id;
int fee;
public:
student(char name[10],int id, int fee): id{id}, fee{fee} // more specialized
{
strcpy(this->name,name); //string copy
}
student(char name[10],int id): student(name, id, 0) { } // less specialized calling the more specialized constructor
void show() //print function
{
cout<<"Name:"<<name<<endl;
cout<<"id:"<<id<<endl;
cout<<"fee:"<<fee<<endl<<endl;
}
};
int main()
{
student s1("DAVID",123);
student s2("WILLIAM",124,5000);
s1.show();
s2.show();
return 0;
}
Here's your code with changes made to get it compiling; I marked the changes with comments.
#include <iostream>
// #include <cstring> // CHANGED: Prefer C++ ways when writing C++
#include <string> // CHANGED: The C++ way
// using namespace std; // CHANGED: Bad practice
class student {
private:
std::string name{}; // CHANGED: Move from C-string to std::string
int id = 0; // CHANGED: Default member initialization
int fee = 0;
public:
// CHANGED: Move from C-string to std::string
student(std::string name, int id)
: name(name),
id(id)
// CHANGED: ^^ Utilize initialization section
{
// CHANGED: Not needed anymore
// strcpy(this->name,name); //string copy
// this->id=id;
// fee=0;
}
student(std::string name, int id, int fee) : student(name, id) {
// CHANGED: Not needed anymore
// student::student(name,id); //calling a constructor of one class
// // within a constructor of same class
// NOTE: Inconsistency with other ctor w.r.t. this->
this->fee = fee;
}
void show() // print function
{
std::cout << "Name:" << name << '\n';
std::cout << "id:" << id << '\n';
std::cout << "fee:" << fee << "\n\n";
}
};
int main() {
student s1("DAVID", 123);
student s2("WILLIAM", 124, 5000);
s1.show();
s2.show();
return 0;
}
Here is the same code, but with the stuff I commented out removed to make it easier to read.
#include <iostream>
#include <string>
class student {
private:
std::string name{};
int id = 0;
int fee = 0;
public:
student(std::string name, int id) : name(name), id(id) {}
student(std::string name, int id, int fee) : student(name, id) {
this->fee = fee;
}
void show()
{
std::cout << "Name:" << name << '\n';
std::cout << "id:" << id << '\n';
std::cout << "fee:" << fee << "\n\n";
}
};
int main() {
student s1("DAVID", 123);
student s2("WILLIAM", 124, 5000);
s1.show();
s2.show();
return 0;
}
The initialization section follows the parameter list and is marked with :. You then initialize each member, in the order they are declared.
In the case of the constructor doing the delegating, you are unable to initialize fee in the initialization section. The error I receive is a delegating constructor cannot have other mem-initializers.
I don't like splitting my initialization like that, and if you insist on delegating constructor calls for this class, implement the most specific constructor and delegate to it with your less specific constructors. I prefer default member initialization as I think it leads to less confusion and written code overall.
The code then compiles and you get the expected output:
Name:DAVID
id:123
fee:0
Name:WILLIAM
id:124
fee:5000
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)
// ^
Im having an issue getting my variable from my original class to print in another class method
Quick example of my issue:
say the variable was declared here in the test.h file:
class player{
private:
int x = 10;
void setX(); //method for setting X from user input
int getX(); //Method for retrieving variable
}
Then in another class method where i want to print X
class inTheWoods{
public:
printInfo();
}
test.cpp file:
void player::setX(){
cout << "Set X to a number:" << endl;
cin >> x
}
int player::getX(){
return x;
}
int inTheWoods::printInfo(){
player playerObj; //Player object to access methods in player class
cout << playerObj.getX();
}
main.cpp:
int main(){
inTheWoods woodsObj;
woodsObj.printInfo();
return 0;
}
Whenever I run my program that resembles this problem the int does not display correctly and throws me a strange negative number. I hope this isnt too much code and that I documented everything correctly
If you want the classes to be in a separate files, it should still work:
Main.cpp
#include <iostream>
#include "inTheWoods.h"
int main()
{
inTheWoods woodsObj;
woodsObj.printInfo();
return 0;
}
Player.h
#pragma once
#include <iostream>
class Player
{
int x = 10;
void setX();
public:
int getX();
};
Player.cpp
#include "Player.h"
void Player::setX()
{
std::cout << "Set X to a number:" << std::endl;
std::cin >> x;
}
int Player::getX()
{
return x;
}
inTheWoods.h
//#pragma once
#include "Player.h"
#include <iostream>
class inTheWoods
{
public:
void printInfo();
};
inTheWoods.cpp
#include "inTheWoods.h"
void inTheWoods::printInfo()
{
Player playerObj; //Player object to access methods in player class
std::cout << playerObj.getX();
}
#pragma once is a preprocessor that prevents multiple includes, in case you didn't know. You can choose to skip it (Visual Studio auto-generated the file with the line).
In summary, these are the changes I needed to make from your implementation:
Move declaration of getX() from private to public.
Add semicolons to the end of every class.
Add a return type to printInfo(). If you don't want a function to return anything, the return type is void. Unless you care declaring a constructor, which doesn't seem to be the case here.
Here is the working one. It's always a good practice to give a constructor, in order to create an instance with some default values. the following code will work hopefully according to your requirements:
main.cpp
#include <iostream>
#include "inTheWoods.h"
int main()
{
inTheWoods woodsObj;
woodsObj.printInfo();
return 0;
}
player.h
#pragma once
class player
{
private:
int m_x;
public:
player();
player(const int& x);
void setX(); //method for setting X from user input
const int& getX()const; //Method for retrieving variable
};
player.cpp
#include "player.h"
#include <iostream>
player::player() // defualt constructor
:m_x(0) {}
player::player(const int& x)
:m_x(x) {} // parameterised
void player::setX()
{
std::cout << "Set X to a number:" << std::endl;
std::cin >> m_x;
}
const int& player::getX()const
{
return m_x;
}
inTheWoods.h
#pragma once
class inTheWoods
{
public:
inTheWoods();
~inTheWoods();
void printInfo();
};
inTheWoods.cpp
#include "inTheWoods.h"
#include "player.h"
#include <iostream>
inTheWoods::inTheWoods() {}
inTheWoods::~inTheWoods() {}
void inTheWoods::printInfo()
{
//Player object to access methods in player class
player playerObj; // will beinitialized with 0
player playerObj2(10); // will beinitialized with 10
std::cout << playerObj.getX() <<std::endl;
std::cout << playerObj2.getX() <<std::endl;
}
Edit: Well if you wanna allow the user to set values your printInfo() must be as follows:
void inTheWoods::printInfo()
{
//Player object to access methods in player class
player playerObj; // will beinitialized with 0
playerObj.setX();
std::cout << playerObj.getX() <<std::endl;
}
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.
I have a multilevel inheritance (from Ship class -> MedicShip class -> Medic class) with virtual function code as below. I suppose the result should be :
Medic 10
Medic 10
But it generated strange result. On the other hand, if I only use one level inheritance (from Ship class -> Medic class without MedicShip class in between) the result will be OK. Could you find my mistake please? Many thank....
#ifndef FLEET_H
#define FLEET_H
#include <string>
#include <vector>
using namespace std;
class Ship
{
public:
Ship(){};
~Ship(){};
int weight;
string typeName;
int getWeight() const;
virtual string getTypeName() const = 0;
};
class MedicShip: public Ship
{
public:
MedicShip(){};
~MedicShip(){};
string getTypeName() const;
};
class Medic: public MedicShip
{
public:
Medic();
};
class Fleet
{
public:
Fleet(){};
vector<Ship*> ships;
vector<Ship*> shipList() const;
};
#endif // FLEET_H
#include "Fleet.h"
#include <iostream>
using namespace std;
vector<Ship*> Fleet::shipList() const
{
return ships;
}
int Ship::getWeight() const
{
return weight;
}
string Ship::getTypeName() const
{
return typeName;
}
string MedicShip::getTypeName() const
{
return typeName;
}
Medic::Medic()
{
weight = 10;
typeName = "Medic";
}
int main()
{
Fleet fleet;
MedicShip newMedic;
fleet.ships.push_back(&newMedic);
fleet.ships.push_back(&newMedic);
for (int j=0; j< fleet.shipList().size(); ++j)
{
Ship* s = fleet.shipList().at(j);
cout << s->getTypeName() << "\t" << s->getWeight() << endl;
}
cin.get();
return 0;
}
You haven't created any instances of class Medic. Did you mean to say
Medic newMedic;
instead of
MedicShip newMedic;
perhaps? So, the Medic constructor isn't being called and weight and typeName aren't being initialized.
~Ship(){};
The first mistake is right here. This destructor should be virtual if you want to delete derived class objects through base class pointer.