Constructor in double inheritance - c++

I have a problem with my constructor. I have class vehicle, then I made class motorVehicle which inherited after vehicle and then I want to make class motorcycle which inherits after class motorVehicle and I can't make my default constructor because I have error:
Class vehicle and motorVehicle isn't changed by me and class motorcycle is in 2 option none of these option works but I give you both of them. Btw the problems are (First option): no matching constructor for initialization of 'motorVehicle' and with second option expected ; after expression and expected member name or ; after declaration specifiers
class vehicle {
public:
int numberOfWheels;
string color;
float vehiclePayload;
vehicle(): numberOfWheels{4},color{"black"},vehiclePayload{500}{
}
};
class motorVehicle : public vehicle {
public:
float tankCapacity;
float fuelConsumption;
float mileage;
float currentAmountOfFuel;
int yearOfProduction;
unsigned long long int vin;
motorVehicle(): tankCapacity{30}, fuelConsumption{6}, mileage{100}, currentAmountOfFuel{10}, yearOfProduction{2021}, vin{1}, vehicle{4, "black", 500} {
}
};
class motorcycle : public motorVehicle{
public:
float bootSize;
string brand;
string model;
motorcycle(): bootSize{500}, brand{"Ninja"}, model{"Kawasaki"}, motorVehicle{30,6,100,10,2021,1,vehicle{4, "black", 500}}{
}
};
class motorcycle : public motorVehicle{
public:
float bootSize;
string brand;
string model;
motorcycle(): bootSize{500}, brand{"Ninja"}, model{"Kawasaki"}, motorVehicle(){30,6,100,10,2021,1,vehicle{4, "black", 500}}{
}
};

Your base classes do not declare any constructor taking actual values. As these classes do declare a default constructor, aggregate initialisation doesn't work: there is a declared constructor, i.e., the class isn't an aggregate. If you want to directly initialise the base class you could use their implicitly generate copy constructor, though. However, you'd still need to populate the content of the class separately as you'll need to created the object using a default constructor:
class motorVehicle : public vehicle {
public:
float tankCapacity;
float fuelConsumption;
float mileage;
float currentAmountOfFuel;
int yearOfProduction;
unsigned long long int vin;
motorVehicle(): tankCapacity{30}, fuelConsumption{6}, mileage{100}, currentAmountOfFuel{10}, yearOfProduction{2021}, vin{1},
vehicle([]{
vehicle rc;
rc.numberOfWheels = 4;
rc.color = "black";
rc vehiclePayload = 500;
return rc;
}()) {
}
};
Obviously, instead of using a lambda function you could have a factor function, let's say makeVehicle(int wheels, std::string const& color, float payload) appropriately initialising the members. There should really be a suitable constructor for vehicle, though.

Related

Explicitly initalize abstract base class constructor with value determined by parameter of derived class constructor

Within my vehicle base class, I have a private member variable, string type (for type of vehicle, ie car, motorbike, tricycle, etc).
#pragma once
using namespace std;
#include <string>
#include <iostream>
class vehicle {
public:
vehicle(string reg, string make, string model, int age, string type);
virtual ~vehicle() = default;
virtual double costPerDay() = 0;
protected:
int age;
int perDayCostCap(int costPD);
double penceToPounds(int pence);
private:
const string type;
string const reg, make, model;
};
One of the derived classes, bike, has a numberOfWheels variable which is to be passed into its constructor. I want to initialize the base class constructor with type bicycle or tricycle depending on the numberOfWheels.
I can not figure out how to achieve this, seeing as the base class constructor has to be initialized before the function body of the child class.
The following shows what I would like to achieve (though, I know this is not possible):
bike::bike(int engineCC, int numOfWheels, string reg, string make, string model, int age)
:engineCC(engineCC), numOfWheels(numOfWheels) {
string tricOrBic = (numOfWheels == 2) ? "bicicle" : "tricicle";
vehicle:reg=reg, make=make, model=model, age=age, type=tricOrBic;
};
Like this?
bike::bike(int engineCC, int numOfWheels, string reg, string make, string model, int age)
: vehicle(reg, make, model, age, numOfWheels == 2 ? "bicycle" : "tricycle")
, engineCC(engineCC)
, numOfWheels(numOfWheels)
{
}
This is normal programming, maybe you had some problem I'm not seeing.

Child Class constructor using private member

I have multiple child classes extending the base class (Media).
When I call the child classses constructor, I am not able to use the private member mBookLateFee's value to do some calculations .. it appears to be using the default 0.0 and not the members contents.
However, if I put the actual value of 1.25 in there it works..
When constructed can the object not initialize from a child classes member?
class Media {
private :
string mCallNumber;
protected:
string mStatus;
string mTitle;
string mType;
int mDaysOverDue = 0;
double mDailyLateFee = 0.0;
double mTotalLateFees = 0.0;
public:
Media(string status, string title, int days=0, string callNum="", string type="", double fee=0.0) : mStatus(status),
mTitle(title), mDaysOverDue(days), mCallNumber(callNum), mType(type), mDailyLateFee(fee) {};
~Media(){};
void setCallNo(string newCallNum);
string getCallNo();
void setHowLate(int numDays);
int getDaysOverDue();
virtual void print();
virtual double getFees() = 0;
};
class Book : public Media {
private:
double mBookLateFee = 1.25;
protected:
string mAuthor;
int mNumPages;
public:
Book(string status, string title, int days, string callNum, string author, int pages=0) :
Media(status, title, days, callNum, "Book", mBookLateFee), mAuthor(author), mNumPages(pages){
mTotalLateFees = mDaysOverDue * mDailyLateFee;
};
double getFees() { return mTotalLateFees;}
void print();
};
The superclass, the parent class, gets constructed before the child class.
When your child class invokes the superclass's, the parent class's constructor, the child class has not been constructed yet. It's mBooklateFee is not yet constructed.
In a manner of speaking, it does not exist yet. Hence, you cannot use it in order to invoke the parent class's constructor.

C++ setting value of derived parameterlized ctor [duplicate]

This question already has answers here:
What are the rules for calling the base class constructor?
(10 answers)
Closed 7 years ago.
Hey guys. I dont know how i suppose to do about setting values to derived classes ctor. And here is my code. I remember something like that build in my class. But i know that we can write something like that build ( xxx():yyy(){,,,};).
Check the main's second object.
#include <iostream>
using namespace std;
class vehicle
{
protected:
string brand;
int wheelNumber;
double maxSpeed=0;
public:
vehicle(){cout<<"default ctor for vehicle"<<endl;}
vehicle(string br1, int wn1, double ms1)
{brand=br1; wheelNumber=wn1; maxSpeed=ms1;}
void setbrand(string br){brand=br;}
string getbrand(string br){return brand;}
void setWN(int wn){wheelNumber=wn;}
int getWN(int wn){return wheelNumber;}
void setMaxS(double ms){maxSpeed=ms;}
double getMaxS(double ms){return maxSpeed;}
~vehicle(){cout<<"dtor for vehicle."<<endl;}
};
class car: public vehicle
{
private:
int numberOfDoors;
string fuelType;
public:
car(){cout<<"default ctor for car"<<endl;}
car(int nOD,string fT){numberOfDoors=nOD; fuelType=fT;}
void setnOD(int nOD){numberOfDoors=nOD;}
int getnOD(int nOD){return numberOfDoors;}
void setfT(string fT){fuelType=fT;}
string getfT(string fT){return fuelType;}
void printFeatures()
{
cout<<endl;
cout<<"brand:"<<brand<<endl;
cout<<"wheelNumber:"<<wheelNumber<<endl;
cout<<"MaxSpeed:"<<maxSpeed<<endl;
cout<<"NumberOfDoors:"<<numberOfDoors<<endl;
cout<<"FuelType:"<<fuelType<<endl<<endl;
}
~car(){cout<<"dtor for car."<<endl;}
};
int main()
{
car *cc;
cc= new car;
cc->setbrand("bmw");
cc->setfT("diesel");
cc->setMaxS(333.25);
cc->setWN(4);
cc->setnOD(6);
cc->printFeatures();
delete cc;
car *xx;
xx= new car;
car(5,"gasoline"):vehicle("mercedes",4,489.12);//Part that i cant figure it out.
xx->printFeatures();
delete xx;
}
The ctor(...):base(...){} syntax is used when defining the derived class constructor, not when instantiating an object. So change the constructor to car to this:
car(int nOD,string fT, string br1, int wn1, double ms1): vehicle(br1, wn1, ms1) {
numberOfDoors=nOD; fuelType=fT;
}
And instantiate your car object like this:
xx= new car(5,"gasoline", "mercedes",4,489.12);
Even better, take advantage of C++'s member-initialization syntax to define your constructors:
vehicle(string br1, int wn1, double ms1)
:brand(br1), wheelNumber(wn1), maxSpeed(ms1)
{}
// ...
car(int nOD,string fT, string br1, int wn1, double ms1)
: vehicle(br1,wn1, ms1), numberOfDoors(nOD), fuelType(fT)
{}
You need to code this into the constructor to get this to work. When you derive from a class the constructor of that derived class needs to take in the parameters for the base constructor and its own construction.
class Base
{
int foo;
public:
Base(int f) : foo(f) {};
};
class Derived : public Base
{
int bar;
public:
Derivced(int f, int b) : Base(f), bar(b) {}
^^^^^^^ ^^^^^^^^^
construct the base part constrcut the derived part
};
So for you example the constructor for car would become:
car(string br1, int wn1, double ms1, int nOD,string fT) : vehicle(br1, wn1, ms1),
numberOfDoors(nOD),
fuelType(fT) {}
Since you are allocating instance of class car which is derived class so it is calling both the ctors. First it will call the ctor of class 'vehicle' and then 'car'. [Read the order of calling ctor in case inheritance]

Trying to use classes and define variables in a c++ header file

I'm trying to make a class and define its variables in the header file. All member's data must be private. I think i got the class working, i just cant seem to get the variables to be defined.
Here's my code:
class myMember
{
public:
myMember();
private:
myMember(char name, double height, double weight, int salary);
};
myMember::myMember();
{
name = "Joe";
height = 5.10;
weight = 170;
salary = 100;
}
If you want your class myMember to have the member variables you are setting in the constructor then you need to declare it like so:
class myMember
{
public:
myMember();
private:
std::string name ;
double height, weight ;
int salary ;
};
Since this is C++ I would use std::string for the name variable, otherwise I left the types the same.
You need to declare the class's fields in the class:
class myMember
{
public:
myMember();
private:
std::string name;
double height;
double weight;
int salary;
};
The private member you've added is a constructor, not a set of fields. If you want to use it as a constructor, make it public, and change the name to a string.
public:
myMember( std::string name, double height, double weight, int salary);

Using a base-class object to represent its derived-class objects

I need a way for a single variable to represent two kinds of objects derived from the same base class.
It's kinda hard to describe but I'll try the best:
Say the base class:
class Rectangle
{
float w;
float h;
const float area() {return w*h;}
};
And the two derived classes:
class Poker : Rectangle
{
int style; // Diamond, Club, ....
int point; // A~10, J, Q, K
};
class BusinessCard : Rectangle
{
string name;
string address;
string phone;
};
Now is it possible to declare an object, which could be either a poker or a business-card?
'cuz the usage below is illegal:
Rectangle* rec;
rec = new Poker();
delete rec;
rec = new BusinessCard();
Polymorphism might be a way but since it's only good for changing base-class' member attributes, I need this object to be able to represent exactly either of the derived objects.
EDIT:
Thanks for the all the answers. The public inheritance , the virtual destructor and even the boost::variant typedef are all fantastic hints.
You can do that. The problem is the inheritance modifier for classes is private. Most of the time, private inheritance is not what you want to use. Instead, declare it explicitly as public:
class Rectangle
{
float w;
float h;
const float area() {return w*h; }; // you missed a semicolon here, btw
virtual ~Rectangle() { } // to make `delete` work correctly
};
class Poker : public Rectangle // note the public keyword
{
int style; // Diamond, Club, ....
int point; // A~10, J, Q, K
};
class BusinessCard : public Rectangle
{
string name;
string address;
string phone;
};
Then your code snippet should work.
You need to change the qualifier for the inheritence to public.
class Poker : public Rectangle
{
int style; // Diamond, Club, ....
int point; // A~10, J, Q, K
};
class BusinessCard : public Rectangle
{
string name;
string address;
string phone;
};
is what you want. Now both classes, BusinessCard and Poker are of type Rectangle.
I need this object to be able to
represent exactly either of the
derived objects.
Don't know if I understand it correct but have a look at boost::variant
typedef boost::variant<Poker, BusinessCard> PokerOrBusinessCard
Now you can access the derived classes with a boost variant visitor class.
Maybe this can be a solution.
I think what you may be looking for is multiple inheritance, where an object can sometimes be a Poker and sometimes a BusinessCard.
See here for a tutorial:
http://www.deitel.com/articles/cplusplus_tutorials/20060225/MultipleInheritance/index.html
Note that you can decide to make it one or the other if you wish, it does not have to be both all of the time, which may satisfy what you need.
Change the subclasses to use public derivation and your code works, with some cleanup. You should also use virtual destructors so the delete works correctly.
class Rectangle
{
float w;
float h;
const float area()
{
return w*h;
}
public:
virtual ~Rectangle(){};
};
class Poker : public Rectangle
{
int style; // Diamond, Club, .... int point; // A~10, J, Q, K
};
class BusinessCard : public Rectangle
{
string name;
string address;
string phone;
};