I have implemented different classes derived from an abstract class and each one has different methods. The problem is that I have to declare the object only at runtime, so I have to create a pointer to the base class and I can't use the methods of each derived class.
I have created an example to explain better what I mean:
#include <iostream>
using namespace std;
class poligon
{
public:
double h, l;
void setPoligon(double h, double l) {
this->h = h;
this->l = l;
}
virtual double GetArea() = 0;
virtual void GetType() = 0;
};
class triangle : public poligon
{
double GetArea() { return l*h / 2; }
void GetType() { cout << "triangle" << endl; }
double GetDiag() { return sqrt(l*l + h*h); }
};
class rectangle : public poligon
{
double GetArea() { return l*h; }
void GetType() { cout << "rectangle" << endl; }
};
void main()
{
poligon* X;
int input;
cout << "1 for triangle and 2 for rectangle: ";
cin >> input;
if (input == 1)
{
X = new triangle;
}
else if (input == 2)
{
X = new rectangle;
}
else
{
cout << "Error";
}
X->h = 5;
X->l = 6;
X->GetType();
cout << "Area = " << X->GetArea() << endl;
if (input == 2)
{
cout << "Diangonal = " << X->GetDiag() << endl; // NOT POSSIBLE BECAUSE " GetDiag()" IS NOT A METHOD OF "poligon" CLASS !!!
}
}
Obviously the method X->GetDiag() at the end of the main can't be used because it is not a method of the "poligon" class.
Which is the correct implementation of a program with this logic?
Introduce a method in the base class
virtual bool boHasDiagonal(void) =0;
Declare unconditionally in base class:
virtual double GetDiag();
Implement it differently in both derived classes:
virtual bool boHasDiagonal(void) {return true;} // rectangle
virtual bool boHasDiagonal(void) {return false;} // triangle
Change output line:
if (X->boHasDiagonal())
{cout << "Diangonal = " << X->GetDiag() << endl;}
For a nice touch of paranoia (a healthy state of mind for a programmer in my opinion), use concept by Gluttton of a default implementation of GetDiag(), which signals an error (as in his answer here) .
For the case of many poligons, I like the proposal by Rakete1111 in the comment.
Define method in the base class which define implementation throws exception:
class poligon
{
public:
virtual double GetDiag()
{
throw std::logic_error ("Called function with inappropriate default implementation.");
}
};
In class that has meaningful implementation override it:
class rectangle : public poligon
{
double GetDiag() override
{
return diagonale;
}
};
Usage:
int main () {
try {
X->GetDiag();
}
catch (...) {
std::cout << "Looks like polygon doesn't have diagonal." << std::endl;
}
}
You can use dynamic_cast.
dynamic_cast<triangle*>(X)->GetDiag();
Note that you already have a bug: You only create a triangle if input == 1, but you get the diagonal if input == 2. Also, the above is not really safe, because dynamic_cast can return nullptr if the conversion is invalid.
But it would be better to check whether dynamic_cast succeeds, then you could also drop the input == 2 check:
if (triangle* tri = dynamic_cast<triangle*>(X))
std::cout << "Diagonal = " << tri->GetDiag() << '\n';
Use dynamic casting to check if the base class' pointer is actually a triangle, like this:
int main()
{
...
if(triangle* t = dynamic_cast<triangle*>(X))
std::cout << "Triangle's diagonal = " << t->GetDiag() << std::endl;
return 0;
}
PS: I assume that your example is just a draft, since it has some bugs.
You use dynamic_cast to access subclass-methods.
It returns nullptr if it is not derived from the class. This is called down cast, as you are going down the class-tree:
triangle* R = dynamic_cast<triangle*>(X);
if(R) {
cout << "Diagonale = " << R->GetDiag() << '\n';
};
Edit: You can put the declaration in the first line into the if-condition, which goes out of scope outside the if-statement:
if(triangle* R = dynamic_cast<triangle*>(X)) {
cout << "Diagonale = " << R->GetDiag() << '\n';
};
if(rectangle* R = ...) {...}; // reuse of identifier
If you want to allow, that multiple subclasses have the GetDiag function you can inherit from the poligon-class and another diagonal-class. The diagonal-class only defines the GetDiag function and has not really to do with the polygon-class:
class polygon {
// stays the same
};
class diagonal {
virtual double GetDiag() = 0;
};
class triangle : public polygon, public diagonal {
// body stays the same
};
And like above, you access the methods via casting with dynamic_cast but this time you cast to type diagonal. This time it is side cast, because poligon has nothing to do with diagonal, so you are going sideways in the tree.
polygon diagonal
| | |
| |_____________|
| |
| |
rectangle triangle
As others have said, you can use dynamic_cast to change the static type in your program, add a method to the base-class with a pseudo implementation or use some form of type-switching. However, I would consider all these answers as signs of a design flaw in your program and would reject the code. They all encode assumptions about the types existing in your program into the code and pose a maintenance burden. Imagine adding new types of shapes to your program. You then have to search and modify all the places you dynamic_cast your objects.
I think your example hierarchy is wrong in the first place. When you declare a base-class for ploygons, and derive triangles from it, the whole purpose of polymorphism is to be able to treat similar objects identically. So anything that is not common behavior (not implementation) is put in the base-class.
class poligon
{
public:
double h, l;
void setPoligon(double h, double l) {
this->h = h;
this->l = l;
}
virtual double GetArea() = 0;
virtual void GetType() = 0;
};
class triangle : public poligon
{
double GetArea() { return l*h / 2; }
void GetType() { cout << "triangle" << endl; }
double GetDiag() { return sqrt(l*l + h*h); }
};
You explicitly say that I can replace any instance of polygon with an instance of triangle everywhere in your program. This is the the Liskov substitution principle. What about circles? They don't have height and length. Can you use a rectangle everywhere you expect a polygon? Currently you can, but polygons can have more edges, be self-intersecting etc. I cannot add a new edge to a rectangle, otherwise it would be a rectangle anymore.
There are some solutions, but as it is a design question, the solution depends on what you want to do with the objects.
A downcast is usually a sign of a bad design and is rarely needed in practice.
I can't see why it is needed in this particular case. You have discarded the information about which type you have for no reason. An alternative could be:
void printDiagonal(const triangle& tri)
{
std::cout << "Diangonal = " << tri.GetDiag() << std::endl;
}
void process(poligon& p)
{
p.h = 5;
p.l = 6;
p.GetType();
std::cout << "Area = " << p.GetArea() << std::endl;
}
int main()
{
int input;
std::cout << "1 for triangle and 2 for rectangle: ";
std::cin >> input;
if (input == 1)
{
triangle tri;
process(tri);
printDiagonal(tri);
}
else if (input == 2)
{
rectangle rect;
process(rect);
}
else
{
std::cout << "Error\n";
}
}
Live demo.
Related
I have to solve this " create class for describing triangle and trapeze with ability to return values and finding S of the figures.. declare function which allows comparing S of the both figures.. in main function declare object triangle and trapeze and compare their areas .. " - im trying to translate it from Bulgarian to English sorry if its not translated correctly ..
Anyways I came up with a solution, but when it asks me to enter value for trapeze x2 times and I can't understand why... it always takes the first 3 entered numbers but I want it to ask for input only once .. sorry if the answer is obvious
//
// main.cpp
// compare S of 2 figures
//
// Created by Георгиос Семерджиев on 17/05/22.
//
#include <iostream>
#include <cmath>
using namespace std;
class Trap // trap class with declared functions inside
{
protected:
double a, c, h;
void setValueTrap();
public:
Trap();
void Print();
virtual double S();
}; // end trap class
class Triangle : public Trap // triangle class with declared function for finding s() print and setting value
{
double b;
void setValueTriangle();
public:
Triangle();
void Print();
virtual double S();
double p(); // returning P/2
}; // end triangle class
// trap functions ...
Trap:: Trap()
{
setValueTrap();
}
void Trap::setValueTrap() // trap input function
{
cout << "Trap enter a = "; cin >> a;
cout << "Trap enter c = "; cin >> c;
cout << "Trap enter h = "; cin >> h;
cout << endl;
}
double Trap::S() // trap calculating and returning s()
{
return ( (a+c) * h ) / 2;
}
void Trap::Print() // printing S() for trap
{
cout << "Trap S = " << S();
cout << endl;
}
// Triangle functions ..
Triangle::Triangle():Trap()
{
setValueTriangle();
}
void Triangle::setValueTriangle() // setting value for triangle a,b,c
{
cout << "Triangle a = "; cin >> a;
cout << "Triangle b = "; cin >> b;
cout << "Triangle c = "; cin >> c;
cout << endl;
}
double Triangle::p() // returning P / 2 = p
{
return (a+b+c) / 2;
}
double Triangle::S() // calculating S() of triangle
{
return sqrt(p() * (p() - a) * (p()-b) * (p()-c));
}
void Triangle::Print()
{
cout << "Triangle S = " << S();
cout << endl;
}
// creating function to compare Trap S() and Triangle S()
bool Compare (Trap *F1, Trap *F2)
{
return F1 -> S() < F2 -> S();
} // compare function
int main()
{
Trap* trap = new Trap();
Triangle* triangle = new Triangle();
trap -> Print(); triangle -> Print();
cout << endl;
if (Compare(trap, triangle))
cout << "the Trap S < Triangle S.." << endl;
else
{
cout << "The Trap S > Triangle S.." << endl;
}
return 0;
}
For the Triangle constructor you have:
Triangle::Triangle():Trap()
{
setValueTriangle();
}
That will explicitly invoke the Trap constructor which read input. Then you will read the input for the triangle.
It's often not a good idea to read input in a constructor. It's usually better to only do basic initialization in the constructor and then get input using the fully constructed object.
Note that even if you don't have the explicit invokation of the Trap constructor, this will happen implicitly.
Triangle inherits from Trap, and both of their constructors are called when constructing Triangle object. To avoid this set up a virtual function setValue and call it only in Trap constructor.
I am making a Poker game in C++, and I am just trying to get started.
I need the ability to compare "Hands", to see which one is greater, equal, or lesser.
So, I have a Hand class now, and I made two other sub-classes that are called Straight and ThreeOfKind (I will add the rest later.
The Hand class has a method called compareTo(Hand* otherHand), it then checks the hand ranking to see which one is better. Also, with the Straights and Three of a Kinds, you can compare them together when they are of the same rank. Like Straights with Straights and Three of a Kinds with Three of a Kinds.
I wrote some initial code today, and my problem is, when I try to call "Hand's" compareTo(Hand* otherHand) method and pass in a Hand, Straight, or Three of a Kind, the compiler complains as it is trying to force me to use the Straight's compareTo(Straight* otherStraight) method. So, I should have overloading, but it's not working.
So in the Straight class after inheritance is done, we should have these two methods:
int Hand::compareTo(Hand* otherHand);
int Straight::compareTo(Straight* otherStraight);
// But, if you do this, it works:
Straight myStraight1 = new Straight(7);
Straight myStraight2 = new Straight(5);
myStraight1.compareTo(myStraight2);
// This is valid...
// If you do this, then the compiler complains!
Straight myStraight3 = new Straight(10);
ThreeOfKind myTrips4 = new ThreeOfKind(3);
myStraight3.compareTo(myTrips4);
// This above line complains that you cannot convert a ThreeOfKind to a Straight
// Even though I am trying to use Hand's compareTo(Hand* otherHand) method and
// cast a Three of a Kind to a Hand object,
// it fails with the overloading!
Here is all the source code...
//////////////////////////
// C++ main header file //
//////////////////////////
#pragma once
class Hand {
private:
int ranking;
public:
Hand(int aRanking);
Hand();
int getRanking();
int compareTo(Hand* otherHand);
};
class Straight : public Hand {
private:
int highCard;
public:
Straight(int aHighCard);
Straight();
int getHighCard();
int compareTo(Straight* otherStraight);
};
class ThreeOfKind : public Hand {
private:
int tripsValue;
public:
ThreeOfKind(int aTripsValue);
ThreeOfKind();
int getTripsValue();
int compareTo(ThreeOfKind* otherThreeOfKind);
};
///////////////////////////
// C++ main .cpp file... //
///////////////////////////
#include <iostream>
#include "PokerTest1.h"
using namespace std;
Hand::Hand(int aRanking) {
this->ranking = aRanking;
}
Hand::Hand() {
this->ranking = 0;
}
int Hand::getRanking() {
return this->ranking;
}
int Hand::compareTo(Hand* otherHand) {
cout << "COMPARING HANDS..." << endl;
if (this->getRanking() < otherHand->getRanking()) {
cout << "HANDS RETURNING -1..." << endl;
return -1;
}
else if (this->getRanking() > otherHand->getRanking()) {
cout << "HANDS RETURNING 1..." << endl;
return 1;
}
cout << "HAND RANKINGS ARE EQUAL..." << endl;
if (this->getRanking() == 4 && otherHand->getRanking() == 4) {
cout << "HANDS ARE BOTH STRAIGHTS..." << endl;
Straight* myStraight1 = (Straight*)this;
Straight* myStraight2 = (Straight*)otherHand;
cout << "COMPARING BOTH STRAIGHTS..." << endl;
return myStraight1->compareTo(myStraight2);
}
else if (this->getRanking() == 3 && otherHand->getRanking() == 3) {
cout << "HANDS ARE BOTH THREE OF A KINDS..." << endl;
ThreeOfKind* myTrips1 = (ThreeOfKind*)this;
ThreeOfKind* myTrips2 = (ThreeOfKind*)otherHand;
cout << "COMPARING BOTH TRIPS..." << endl;
return myTrips1->compareTo(myTrips2);
}
return 0;
}
Straight::Straight(int aHighCard) : Hand(4) {
this->highCard = aHighCard;
}
Straight::Straight() : Hand(4) {
this->highCard = 0;
}
int Straight::getHighCard() {
return this->highCard;
}
int Straight::compareTo(Straight* otherStraight) {
cout << "INSIDE STRAIGHT COMPARE TO..." << endl;
if (this->highCard < otherStraight->highCard) {
cout << "STRAIGHT COMPARE RETURNING -1..." << endl;
return -1;
}
else if (this->highCard > otherStraight->highCard) {
cout << "STRAIGHT COMPARE RETURNING 1..." << endl;
return 1;
}
cout << "STRAIGHT COMPARE RETURNING 0..." << endl;
return 0;
}
ThreeOfKind::ThreeOfKind(int aTripsValue) : Hand(3) {
this->tripsValue = aTripsValue;
}
ThreeOfKind::ThreeOfKind() : Hand(3) {
this->tripsValue = 0;
}
int ThreeOfKind::getTripsValue() {
return this->tripsValue;
}
int ThreeOfKind::compareTo(ThreeOfKind* otherThreeOfKind) {
cout << "INSIDE STRAIGHT COMPARE TO..." << endl;
if (this->tripsValue < otherThreeOfKind->tripsValue) {
cout << "TRIPS COMPARE RETURNING -1..." << endl;
return -1;
}
else if (this->tripsValue > otherThreeOfKind->tripsValue) {
cout << "TRIPS COMPARE RETURNING 1..." << endl;
return 1;
}
cout << "TRIPS COMPARE RETURNIN 0..." << endl;
return 0;
}
int main()
{
// Test the classes...
// with Straight compared to a Three of a Kind.
// Should try to invoke Hand::compareTo(Hand* otherHand) { ... };
// But, instead, it try to invoke Straight::compareTo(Straight* otherStraight) { ... };
// If you put both these methods in the Straight class (rather than using inheritence, it works)
// If you delete Straight::compareTo(Straight* otherStraight) { ... }, the line below compiles
// It is just strange why it won't compile...
Straight* myStraightA = new Straight(9); // Straight of 5, 6, 7, 8, 9
ThreeOfKind* myTripsB = new ThreeOfKind(2); // Three of a Kind of 2, 2, 2
cout << "Compare results..." << endl;
cout << myStraightA->compareTo(myTripsB) << endl; // Compiler error...
return 0;
}
Also, here is a list of the hand rankings:
0 → high card
1 → pair
2 → two pair
3 → three of a kind
4 → straight
5 → flush
6 → full house
7 → quads
8 → straight flush
9 → royal flush
Basically I have a field in the Hand class that stores these rankings as integers. Just so you know.
Lastly, this is the compiler error message:
error C2664: 'int Straight::compareTo(Straight )': cannot convert argument 1 from 'ThreeOfKind' to 'Straight*'
You are trying to overload across classes.
The compiler looks for a compareTo method, finds it in Straight, and doesn't look at Hand. If you add an appropriate using statement, you can tell it to look at Hand's compareTo as well to accomplish your overloading.
class Straight : public Hand {
private:
int highCard;
public:
using Hand::compareTo; // <<< HERE
Straight(int aHighCard);
Straight();
int getHighCard();
int compareTo(Straight* otherStraight);
};
Instead of doing this, I'd recommend you use getRanking() for comparison between hands of different hand types, and define getTieBreaker() overridden by subclasses to handle cases of the same type of hand.
class Hand {
public:
int getRanking();
// virtual causes subclass' version to be called if done from reference or pointer.
virtual int getTieBreaker();
};
This simplifies how Hand compares:
int Hand::compareTo(Hand* otherHand) {
if (this->getRanking() < otherHand->getRanking()) {
return -1;
}
else if (this->getRanking() > otherHand->getRanking()) {
return 1;
}
if (this->getTieBreaker() < otherHand->getTieBreaker()) {
return -1;
}
else if (this->getTieBreaker() > otherHand->getTieBreaker()) {
return 1;
}
return 0;
}
And lets you define it in Straight:
class Straight : public Hand {
//...
public:
int getHighCard();
int getTieBreaker();
};
int Straight::getTieBreaker() {
return this->highCard;
}
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) {}
Hello I have two questions. First, here is some code. I am new to c++. I have to calculate the square of rectangle by the x,y coordinates of upper left and lower right corner - downRightx, upperLeftx, downRighty, upperLefty, the diagonal, and the sides of rectangle. I must make a function print() that calls other private functions only to show the result. Everything is defined inside the class.
class rectangle {
private:
double uLx, uLy, dRx, dRy;
public:
rectangle() {
cout << "enter x coordinate of upper left corner" << uLx;
cout << "enter y coordinate of upper left corner" << uLy;
cout << "enter x coordinate of down right corner" << dRx;
cout << "enter y coordinate of down right corner" << dRy;
}
~rectangle() {
cout << "Deleting object" << endl;
}
private:
void sides() {
double a, b;
a = sqrt(pow((dRx - uLx), 2));
b = sqrt(pow((dRy - uLy), 2));
}
void facediag() {
double s, d;
d = sqrt(pow((dRx - uLx), 2) + pow((dRy - uLy), 2));
---- 1. //here must be the calculation of square s = a*b
}
public:
void print() {
--- 2. //here I must print the results
}
};
so the question is: How to call a and b parameters from side in facediag() function to calculate s = a*b And how to print the results. Can I write cout << a; cout << d; cout << s, etc. in sides() and facediag() and just call them in print? Or can I print them in print() without writing cout << ... in other functions, but otherwise, another access method.
void facediag(){
//code
cout << s;
cout << d;
}
void sides(){
// code
cout << a;
cout << b;
}
void print()
{
sides();
facediag();
}// not like this, is there another way?
Second question I let Cygwin to be installed at its complete form and at some point I realized that I will run out of hdd and the installation hangs, so I interrupted the installation. How can I uninstall it - just delete the folder or to step through the FAQ in the Cygwin site?
You cannot access local variables from other functions. They only exist while that function executes.
What you can do is define more member functions that compute the values you need, like
double height() const
{ return /* something */; }
double width() const
{ return /* something else */; }
and use those functions where you need a or b.
You CAN call the private function in your OWN class.
But, the variable a and b are local variables, so they will not exist out of the function sides(), you can do the same thing in function facediag() to calculate a and b
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.