print sum of data members of child classes in parent function [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
#include <iostream>
using namespace std;
class Fruit {
protected:
int nr_fruits = 0;
public:
void printTotal() {
cout << "Total fruits in the basket: " << nr_fruits << endl;
}
};
class Mango : public Fruit {
int nr_mangoes;
public:
void getMango(int x) {
nr_mangoes = x;
cout << "There are " << nr_mangoes << " mangoes in the basket" << endl;
nr_fruits = nr_fruits + nr_mangoes;
}
};
class Apple : public Fruit {
int nr_apples;
public:
void getApple(int x) {
nr_apples = x;
cout << "There are " << nr_apples << " apples in the basket" << endl;
nr_fruits = nr_fruits + nr_apples;
}
};
int main(int argc, const char * argv[]) {
Apple a1;
Mango m1;
a1.getApple(10);
a1.printTotal();
m1.getMango(20);
m1.printTotal();
return 0;
}
I need to make a function in the parent class Fruit, to be able to print the number of total fruits, in my case, nr_mangoes + nr_apples.
Obviously, the way i do it, the nr_fruits variable will output only the amount of mangoes or the amount of apples as the total amount of fruit.
How can i get to access the data members of the child classes, or make the variable nr_fruits so that it keeps the value throughout the program.

In this case you need the use of inheritance.
You will use virtual functions.
You will have to store in a vector of pointers to fruit, all the fruits you have.
vector<Fruit*> MyFruits;
Inside class Fruit you will implement a virtual function:
virtual int get_num_of_fruits(){}
And inside the child classes:
int get_num_of_fruits(){
return nr_child; //nr_apples,nr_mangos etc.
}
Then you will have an int nr_fruits = 0 and add to the number of all the fruits(apples,mangos etc.)
So, nr_fruits += MyFruits[i]->get_num_of_fruits(); for i = 0 to i<MyFruits.size()

In the case of your example and for simplicity, you can change your nr_fruits variable to be static, then initialize it after the class declaration:
class Fruit {
public:
static int nr_fruits;
void printTotal() {
cout << "Total fruits in the basket: " << nr_fruits << endl;
}
};
int Fruit::nr_fruits = 0;
However, without knowing the full scope of the requirements for your program, I think you may want to consider to design a better approach to your problem...

Related

Send abstract object from main thread to others thread [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I'm doing a pizzeria restaurant simulation, where the main thread is the Reception, it can take orders and transform it in abstract pizza object APizza, in this reception i have a kitchen object, which contain a list of cooks represented by threads (std::list< std::thread > _cooks) i want to pass theses abstract pizzas from the reception main thread, to my sub-threads cooks, and i want them to be able to pick from the ingredient stock (Stock *_ingredients) in the kitchen main threads, i know i must use mutex to lock ingredients stock variable before modifying it so many cooks won't access and change the data in the stock at the same time do unpredictable behavior.
I'm looking for some approach to passe theses pizzas and to make my main thread kitchen ingredient stock (Stock *_ingredients) stock accessible from the cooks.
Here's my architecture:
class Reception
{
public:
Reception(double, size_t, size_t);
~Reception();
int Shell();
APizza *MakeOrder(PizzaType, PizzaSize);
void openKitchen();
private:
int parseCommands();
std::map<size_t, pid_t> _kitchenList;
protected:
double _multiplier; //Cooking time multiplier.
size_t _cooks; //Number of cook(s) per kitchen.
size_t _restock; //Time in ms to restock ingredients.
};
class Kitchen
{
public:
Kitchen(double, size_t, size_t);
~Kitchen();
APizza *MakeOrder(PizzaType, PizzaSize);
void Status();
void DispatchPizza(APizza *pizza);
bool isFull();
private:
std::stack<APizza> \
_pizzaWaiting;
std::list<std::thread> _cooks;
Stock *_ingredients;
double _multiplier; //Cooking time multiplier.
size_t _ncooks; //Number of cook(s) per kitchen.
size_t _restock; //Time in ms to restock ingredients.
size_t _ordersNow;
//Pipe _pipe;
};
class Cook
{
public:
Cook(double _multiplier);
~Cook();
void Run();
bool canCook();
void cookPizza(APizza *);
private:
APizza *_currPizza;
bool _isCooking;
double _multiplier;
};
Here is where i want to pass the pizza
int Reception::Shell()
{
std::string command;
std::cout << "> ";
std::list<std::string> orders;
APizza *currPizza;
>> Kitchen *kitch = new Kitchen(_multiplier, _cooks, _restock);
while (1)
{
getline (std::cin, command);
if (!command.compare("exit") || std::cin.eof())
return(0);
else
{
orders = splitStr(command, ';');
}
if (!orders.empty())
{
for (const std::string & order : orders)
{
size_t nPizza = getPizzaNbr(order);
PizzaType tPizza = getPizzaType(order);
PizzaSize sPizza = getPizzaSize(order);
if (nPizza == 0 || tPizza == (PizzaType)0 || sPizza == (PizzaSize)0) {
std::cout << "wrong input: " << nPizza << " " << tPizza << " " << sPizza << std::endl;
continue;
}
std::cout << "good input: " << nPizza << " " << tPizza << " " << sPizza << std::endl;
for (size_t i = 0; i != nPizza; i++)
{
currPizza = this->MakeOrder(tPizza, sPizza);
//
// SEND this currPizza to to kitchen cook's thread
//
std::cout << "Nouvelle pizza, type: " << currPizza->getType() \
<< " size: " << currPizza->getSize() << std::endl;
}
}
}
std::cout << std::endl << "> ";
}
return 0;
}
Honestly, just skipped through your code, there's a well-known trick in C++ in which you create a class that encapsulated pthread and passes the self pointer (this) to a new thread, I'll add some references, what I would generally recommend, create a general worker abstract class, whilst cook inherits from, the cook ctor gives it access to these abstract pizzas through the constructor or some setter function, here's an example:
class some_thread
{
public:
some_thread_ctr(pizza_list * your_pizza_list) {};
void start_thead()
{
pthread_create(&i, 0, somethread_main, this);
}
static void * somethread_main(void * somethread_ctx)
{
some_thread * ctx = (some_thread *) somethread_ctx;
// Do actual thing
}
pthread_t i;
};
int main (void)
{
pizza_list pz = new_pizza_list();
some_thread first_cook(pz);
some_thread second_cook(pz);
first_cook.start_thead();
second_cook.start_thead();
}
now this solves your problem as you can simply initialize an abstract pizza list from your main thread, give access to your cook-threads via shared memory (which would be passed on in your constructor) and just run them simultaneously, I must emphasize though that the function somethread_main which in this context represents the main of your cook thread, should be thread safe and it is up to you to access pizza_list in each thread safely with mutexes.
also, I've written the code without compiling it so it might now compile yet the concept itself should help you,
EDIT:
as mentioned in the comments, you could definitely use std::thread instead of pthread_create, this is just a concept of passing this pointer to some function and using that function as a thread entry point thus allowing you to access its data members

access protected variable in derived class c++

I have a mother class and a derived daughter class. I am trying to access the protected variable 'familystuff' in the derived class. Both ways that I am trying to access it aren't working. When I compile and run it, I get the following output:
5 3 1
1
Familie 32768
FOO 32767
class Mother
{
private:
int motherstuff;
protected:
int familystuff;
public:
int everyonesstuff;
void SetStuff(int a, int b, int c){
motherstuff = a;
familystuff = b;
everyonesstuff = c;
}
void Show(){
cout << motherstuff << " " << familystuff << " " <<everyonesstuff << endl;
}
};
class Daughter : public Mother
{
public:
Daughter()
{
a = familystuff + 1;
}
void Show(){
cout << "Familie " << a << endl;
}
int foo() { return familystuff;}
private:
int a;
};
int main(){
Mother myMum;
myMum.SetStuff(5,3,1);
myMum.Show();
cout << myMum.everyonesstuff << endl;
Daughter myDaughter;
myDaughter.Show();
cout << "FOO " << myDaughter.foo() << endl;
}
You don't have a clear concept in object oriented programming. When you create two objects, then they are completely different from each other. They do not interact with each other until they are forced.So,
myMum and myDaughter are seperate objects and they do not share the values of their variables.
The last two outputs are basically garbage values. You have not initialized myDaughter's familystuff
So, if you want to access protected members from derived class, you need to write the following :
int main()
{
Daughter myDaughter(5,3,1);
myDaughter.Show();
cout << "FOO " << myDaughter.foo() << endl;
}
Change the Daughter's constructor to the following :
Daughter(int x,int y,int z)
{
SetStuff(x,y,z);
a = familystuff + 1;
}
You will get the desired output!!
There are several things wrong here:
myDaughter and myMum are different objects. You imply some kind of relationship between them, but there is none.
Your code has undefined behaviour, because your Daughter constructor uses the uninitialised member variable familystuff in an addition operation.
You should initialise your data members like this:
Mother::Mother() : motherstuff(0), familystuff(0), everyonesstuff(0) {}
Daughter::Daugher() : a(familystuff + 1) {}

(C++ Beginner) How do I call these class functions into the main? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I keep having errors, I'm not sure how to call this Car class into the main function. The instructions I was given are below.
#include <iostream>
#include <string>
class Car{
public:
Car(){
int year = 1990;
std::string make = "Bentley";
int speed = 0;
};
Car(int new_year, std::string new_make, int new_speed) {
year = new_year;
make = new_make;
speed = new_speed;
}
int get_year() { return year; }
std::string get_make() { return make; }
int get_speed() { return speed; }
void accelerate() {
speed+=5;
}
void brake() {
speed-=5;
}
private:
int year;
std::string make;
int speed;
};
int main()
{
int year = 1990;
std::string make = "Bentley";
int speed = 0;
Car YourCar(year, make, speed);
std::cout << "Year: " << YourCar.get_year << std::endl;
std::cout << "Make: " << YourCar.get_make << std::endl;
std::cout << "Speed: " << YourCar.get_speed << std::endl;
}
Instructions:
Please implement a class named Car in C++ that has the following member
variables:
year. An int that holds the car’s model year.
make. A string object that holds the make of car.
speed. An int that holds the car’s current speed.
In addition, the class should have the following member functions:
Constructor. The constructor should accept the car’s year and make
as arguments and assign these values to the object’s year and make
member variables. The constructor should initialize the speed member
variable to 0.
Accessors or Getters. Appropriate accessors or getters should allow
values to be retrieved from an object’s year, make and speed member
variables.
accelerate. The accelerate function should add 5 to the speed member
variable each time it’s called.
brake. The brake function should subtract 5 from the speed member
variable each time it is called.
Demonstrate the class in a program that creates a Car object and then
calls the accelerate function 5 times. After each call to the accelerate function,
get the current speed of the car and display it. Then, call the brake
function 5 times. After each call to the break function, get the current speed
of car and display it.
Change
Car(){
int year = 1990;
std::string make = "Bentley";
int speed = 0;
};
to
Car(){
year = 1990;
make = "Bentley";
speed = 0;
}
You don't need to specify the data type here.
next,
std::cout << "Year: " << YourCar.get_year << std::endl;
std::cout << "Make: " << YourCar.get_make << std::endl;
std::cout << "Speed: " << YourCar.get_speed << std::endl;
Should be
std::cout << "Year: " << YourCar.get_year() << std::endl;
std::cout << "Make: " << YourCar.get_make() << std::endl;
std::cout << "Speed: " << YourCar.get_speed() << std::endl;
You forgot the () after the functions.

Reiterating through class vectors C++

I am still wrapping my head around classes and am still new to C++. My assignment is:
Create three small classes unrelated by inheritance - classes
Building, Car and Bicycle. Give each class some unique appropriate
attributes and behaviors that it does not have in common with other
classes.
Write an abstract class CarbonFootprint with only a pure virtual
getCarbonFootprint method.
Have each of your classes inherit from that abstract class and
implement the getCarbonFootprint method to calculate an appropriate
carbon footprint for that class (check out a few websites that explain
how to calculate carbon footprints).
Write an application that creates objects of each of the three
classes, places pointers to those objects in a vector of
CarbonFootprint pointers, then iterates through the vector,
polymorphically invoking each object's getCarbonFootprint method.
For each object, print some identifying information and the object's
carbon footprint.
I am having trouble trying to figure out how to iterate through my vector <CarbonFootPrint>. I also do not know if the objects being created are actually being put into this vector. My code so far is:
#include <iostream>
#include <vector>
using namespace std;
class CarbonFootPrint
{
//class declarations
public:
virtual double getCarbonFootPrint();
};
//class implementation
double CarbonFootPrint::getCarbonFootPrint()
{
return 0;
}
class Building : CarbonFootPrint
{
//class declarations
public:
Building(double e = 0, int m = 12); //constructor
~Building(); //destructor
double setElectric();
virtual double getCarbonFootPrint();
private:
double electric;
int months;
};
//class implementation
Building::Building(double e, int m)
{
electric = e;
months = m;
}
Building::~Building()
{
}
double Building::setElectric()
{
cout << "Enter your monthly electric in KWH: " << endl;
cin >> electric;
return electric;
}
double Building::getCarbonFootPrint()
{
//I would like to print out the variable information for each object created
//and then
cout << "The carbon footprint for this house is " << endl;
//when it iterates through the vector.
return(electric * months);
}
class Car : CarbonFootPrint
{
public:
Car(double = 0, double = 0); //constructor
~Car(); //destructor
double setYearlyMiles();
double setAverageMPG();
virtual double getCarbonFootPrint();
private:
double yearlyMiles, averageMPG;
int co2 = 9;
};
//class implementation
Car::Car(double ym, double mpg)
{
yearlyMiles = ym;
averageMPG = mpg;
}
Car::~Car()
{
}
double Car::setYearlyMiles()
{
cout << "Enter in your yearly miles: " << endl;
cin >> yearlyMiles;
return yearlyMiles;
}
double Car::setAverageMPG()
{
cout << "Enter in your average miles per gallon: " << endl;
cin >> averageMPG;
return averageMPG;
}
double Car::getCarbonFootPrint()
{
//I would like to print out the variable information for each object created
//and then
cout << "The carbon footprint for this car is " << endl;
//when it iterates through the vector.
return((yearlyMiles * averageMPG) * co2);
}
class Bicycle : CarbonFootPrint
{
public:
Bicycle(double = 0, int = 34); //constructor
~Bicycle(); //destructor
double setMiles();
virtual double getCarbonFootPrint();
private:
int calories;
double miles;
};
//class implementation
Bicycle::Bicycle(double m, int c)
{
miles = m;
calories = c;
}
Bicycle::~Bicycle()
{
}
double Bicycle::setMiles()
{
cout << "Enter in number of miles: " << endl;
cin >> miles;
return miles;
}
double Bicycle::getCarbonFootPrint()
{
//I would like to print out the variable information for each object created
//and then
cout << "The carbon footprint for this bicycle is " << endl;
//when it iterates through the vector.
return (miles * calories);
}
Here is my main program:
int main()
{
vector <CarbonFootPrint> *list;
int answer, i;
cout << "Welcome to the Carbon Footprint Calculator!\n" << endl;
do
{
cout << "Main Menu\n" << endl;
cout << "1: Set house info.\n" << endl;
cout << "2: Set car info.\n" << endl;
cout << "3: Set bicycle info.\n" << endl;
cout << "4: Get carbon footprint for all items set.\n" << endl;
cin >> answer;
switch (answer)
{
case 1:
{
cout << "\n" << endl;
Building *anotherBuilding;
anotherBuilding = new Building;
anotherBuilding->setElectric();
cout << "\n" << endl;
break;
}
case 2:
{
cout << "\n" << endl;
Car *anotherCar;
anotherCar = new Car;
anotherCar->setYearlyMiles();
anotherCar->setAverageMPG();
cout << "\n" << endl;
break;
}
case 3:
{
cout << "\n" << endl;
Bicycle *anotherbike;
anotherbike = new Bicycle;
anotherbike->setMiles();
cout << "\n" << endl;
break;
}
case 4:
{
//have it iterate through the vector and print out each carbon footprint.
break;
}
default:
{
cout << answer << " is not a valid option" << endl;
break;
}
}
}
while (answer != 4);
system("pause");
return 0;
}
Any help or guidance is greatly appreciated! Thank you for your time!
Re: your comments on R Sahu's post (I'm too new to be allowed to comment on other posts)
You cannot access the base class because it has defaulted to private,
class Building : CarbonFootPrint
class Car : CarbonFootPrint
class Bicycle : CarbonFootPrint
are all inheriting from CarbonFootPrint privately, which represents a "has-a" relationship, in this case although semantically a car has-a carbon foot print you're actually trying to make an "is-a" relationship, as these are all objects that implement the base class, possibly a better name for CarbonFootPrint could be CarbonFootPrintProducer.
The fix here is simply make them all publically inherited
class Name : public Base
You missed a crucial thing from:
Write an application that creates objects of each of the three classes, places pointers to those objects in a vector of CarbonFootprint pointers, then iterates through the vector, polymorphically invoking each object's getCarbonFootprint method.
Instead of
vector <CarbonFootPrint> *list; // Pointer to a vector of CarbonFootPrint objects.
You need to use
vector <CarbonFootPrint*> list; // A vector of CarbonFootPrint pointers.
Instead of
{
cout << "\n" << endl;
Building *anotherBuilding;
anotherBuilding = new Building;
anotherBuilding->setElectric();
cout << "\n" << endl;
break;
}
Use
{
cout << "\n" << endl;
Building *anotherBuilding;
anotherBuilding = new Building;
anotherBuilding->setElectric();
// Add the pointer to the list of pointers.
list.push_back(anotherBuilding);
cout << "\n" << endl;
break;
}
Make similar changes to the other object types.
At the end, call CarbonFootPrint() on the objects:
for (auto item : list )
{
item->CarbonFootPrint();
}
and delete the objects:
for (auto item : list )
{
delete item;
}
R Sahu covered almost all of it, the only bit I see remaining is;
Write an abstract class CarbonFootprint with only a pure virtual getCarbonFootprint method.
to which your class is not abstract as the function is not pure virtual, to do this simply add = 0
virtual double getCarbonFootPrint() = 0;
Pure virtual functions are ones that don't count as implemented, any class containing a pure virtual function is called "abstract" and cannot be instantiated. In this case it would have helped you identify your vector of CarbonFootPrint rather than CarbonFootPrint* to them, as the instantiations would be picked up by the compiler, although knowing template compiler errors you'd have had a couple hundred lines of error message for this simple mistake.
For full disclosure: a pure virtual function can actually be defined, e.g.;
virtual double getCarbonFootPrint() = 0;
double CarbonFootPrint::getCarbonFootPrint()
{
// some code
return 0;
}
which can then be called from any derived class
double Building::getCarbonFootPrint()
{
return CarbonFootPrint::getCarbonFootPrint();
}
This is legal C++, allows you to define a default implementation, and still CarbonFootprint is an abstract class.

Need Help Getting Classes to Interact With Each Other [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
So basically, I have to write a program that is kind of like an RPG game where there are different types of creatures. Each creature is an object of the class Creature, and has member variables for hitpoints, strength, etc.
What I am having trouble with is writing the function that handles dealing and taking damage between the classes.
#include <iostream>
#include <string>
#include <stdlib.h>
using std::cout;
using std::cin;
using std::endl;
using std::string;
//Creature Base Class (Type 0)
class Creature
{
public:
Creature(int, int, int);
int gettype() {return type;}
int getstrength(){return strength;}
int gethitpoints() {return hitpoints;}
void sethitpoints(int);
string getspecies();
void printstats();
void dealdamage(Creature, Creature);
void takedamage(int);
private:
int type;
int strength;
int hitpoints;
};
Creature::Creature(int t, int s, int hp)
{
type = t;
strength = s;
hitpoints = hp;
}
void Creature::printstats()
{
cout << "This creature has: " << endl;
cout << strength << " strength" << endl;
cout << hitpoints << " hitpoints" << endl;
cout << "and is of type " << type << "(" << getspecies() << ")" << endl;
}
void Creature::sethitpoints(int a)
{
hitpoints = a;
}
string Creature::getspecies()
{
switch(type)
{
case 0: return "Creature";
case 1: return "Human";
case 2: return "Elf";
case 3: return "Demon";
case 4: return "Balrog";
case 5: return "Cyberdemon";
}
}
void Creature::dealdamage(Creature dealer, Creature target)
{
srand(5);
int damage;
damage = rand() % strength+1;
cout << dealer.getspecies() << " inflicts " << damage;
cout << " damage to " << target.getspecies() << "!" << endl;
target.takedamage(damage);
}
void Creature::takedamage(int damage)
{
sethitpoints((gethitpoints()-damage));
}
int main()
{
Creature monster1(0, 10, 100);
Creature monster2(1, 7, 90);
monster1.printstats();
monster2.printstats();
monster1.dealdamage(monster1, monster2);
monster2.printstats();
return 0;
}
Right now, the output the program gives me is:
This creature has:
10 strength
100 hitpoints
and is of type 0(Creature)
This creature has:
7 strength
90 hitpoints
and is of type 1(Human)
Creature inflicts 5 damage to human!
This creature has:
7 strength
90 hitpoints
and is of type 1(Human)
So the dealdamage() function seems to be working, but the takedamage() function is not properly changing the hitpoints of the creature that is taking the damage.
Any help would be appreciated.
The problem is
void Creature::dealdamage(Creature dealer, Creature target)
Firstly, this is called "pass by value". New "Creature" objects are constructed and the values of the "Creature" objects you call the function with are copied into them. The procedure executes, and these temporary Creature objects EOL - the original Creature objects are never touched.
You need to take a pointer or a reference to the original object. But unless you are intending to support some kind of 3-way fight, you shouldn't be requiring both items anyway -- this is a non-static member function, so it's already operating in the context of one of the creatures, hence the syntax with which you invoked it:
monster1.dealdamage(monster1, monster2);
Change your dealdamage like this:
void Creature::dealdamage(Creature& target) // takes a reference
{
//srand(5); <- this will cause rand() to always return the same value. dont do it.
//int damage; <- don't separate declaration and assignment when you can avoid it.
int damage = rand() % strength+1;
cout << getspecies() << " inflicts " << damage
<< " damage to " << target.getspecies() << "!" << endl;
target.takedamage(damage);
}
You can use this->getspecies() if you find just using getspecies() unclear.
Instead of srand(constant value) try something like 'srand(time(NULL))', or better still, do it once at the start of the program.