Hi everybody=) the problem: Compilier can't executed a constructor of class oper because there is no default constructors in class person.
text of error:
'person' : no appropriate default constructor available
the question is: How I can solve this problem without creating default constructors and without inheritance.
here is the code of class person:
class person:public gsm
{
public:
string name,tel;
int tax;
public:
person(string m);
person(string m,string t,string n,int a);
void input(string n, string t, int tx);
void output();
person& operator=(person& a);
bool operator==(person& a);
bool operator!=(person& a);
};
and this is class operator:
class oper
{
private:
person b[10];
int mid_tax1,mid_tax2;
public:
oper();
void set_t1(int tax);
void set_t2(int tax);
void count();
void add_person(person a,int i);
void out();
};
constructor of class oper:
oper::oper()
{
this->mid_tax1=0;
this->mid_tax2=0;
for(int i=0;i<10;i++)
{
b[i].tel="";
b[i].name="";
b[i].tax=0;
}
}
class oper contains 10 instances of person. To build oper you have to build the 10 instances.
When you are in the constructor of oper::oper you are after the class and its contents were constructed. Since there is no default constructor for person there is no way for the compiler to build oper.
Why aren't you allowed to use a default constructor?
Why are you creating a fixed array of 10 people and then support a function called add_person? Is the number of people fixed or dynamic?
If you are using C++03 / C++11 you can use initializer lists to pass the values to the Ctor of person during construction. But it will not be a pretty piece of code.
oper::oper()
: b({""},{""} .... ), mid_tax1(0), mid_tax2(0)
{
...
}
The correct solution is either adding a default constructor or moving away from a fixed array of 10 persons to a dynamic container of N persons
use std::list instead of the array.
Related
I'm trying to write a Swap function to swap 2 different types of objects of an array in C++. How can I do that? (I prefer using pointer to solve this problem)
I've tried to use template classes to swap 2 objects because the types of object are different from others and when looping through the array, I don't know which objects that one element belongs to.
I have 3 classes (Object_A, Object_B and Object_C) as below:
class Object_A : public base_class
{
private:
int workingTime;
int relaxTime;
float salary;
public:
Object_A();
virtual ~Object_A();
float Cal_Salary();
int getWorkingTime() const;
void setWorkingTime(int workingTime);
int getRelaxTime() const;
void setRelaxTime(int relaxTime);
float getSalary() const;
void setSalary(float salary);
};
class Object_B : public base_class
{
private:
float income;
public:
Officer();
virtual ~Officer();
float getIncome() const;
void setIncome(float income);
};
class Object_C : public base_class
{
private:
std::string role;
float roleCoef;
float bonus;
public:
Manager();
virtual ~Manager();
float Cal_Bonus();
const std::string& getRole() const;
void setRole(const std::string& role);
float getRoleCoef() const;
void setRoleCoef(float roleCoef);
float getBonus() const;
void setBonus(float bonus);
};
// I tried to write SwapValues func
template<class T, class U>
void SwapValues(T* a, U* b)
{
T temp = a;
a = b;
b = temp;
}
I have an array with base_class type to store some elements of three objects above (Object_A, Object_B and Object_C).
However when I want to swap one element of Object_A to one of Object_C with SwapValues() func, it doesn't work!
Thanks a lot for your help.
EDIT: Re-reading your question, the reason why your pointerswap doesn't work is because you are not passing the pointers as reference. If you insist on calling the function SwapValues, you can implement it like this:
class base_class {
// ...
friend void SwapValues(base_class*& a, base_class*& b) {
::std::swap(a,b);
}
};
Observe that SwapValues is still free function, not a member function.
You should always use ::std::swap as it sometimes offers efficient alternatives:
::std::swap(*a,*b);
You can also implement a member function in your class if you want to customise how swap works. For instance, your members can be swapped efficiently, as they are either POD or ::std::string which has a constant-time swap.
I think you should try
void SwapValues(T* a, U* b)
{
T* temp = a;
a = b;
b = temp;
}
Since your array consists of pointers (base_class* elements), you don't need your own swap function. You can just assign such pointers normally, and thus you can just use std::swap.
I have two classes, one "bank" and one "account". Account's constructor takes an int and a string. Bank is supposed to have two objects of type "account" in it. Is it possible to have the two "account" objects in the fields initializer list be allocated dynamically and not with static values?
Here is the code I have that allocates it statically
class Bank
{
public:
Bank():checkings( 500, "C"), saving( 300, "s"){} //predfined int and string
private:
Account checkings;
Account saving;
};
Is it possible to do this? I want the constuctor to have its fields allocated dynamically according to user input. I keep getting errors so I am unsure if my syntax is wrong.
class Bank
{
public:
Bank():checkings( int val, string s), saving( int val, string s){} //dynamic
private:
Account checkings;
Account saving;
};
Also, how do I call this type of constructor in the .cpp file?
You can't put declarations (like int val) in a member initializer, only expressions (which can be/include previously declared variables).
It looks like maybe you want:
class Bank
{
public:
Bank(int val, std::string s) : checkings(val, s), saving(val, s) {}
// ...
};
or:
class Bank
{
public:
Bank(int check_val, std::string check_s,
int sav_val, std::string sav_s) :
checking(check_val, check_s), saving(sav_val, sav_s) {}
// ...
};
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]
In below example,
class Car
{
private:
int sides;
public:
Car()
{
cout<<"\ndefault called constructor";
}
Car(int nsides)
{
cout<<"\ncalled constructor";
sides=nsides;
}
};
class Auto
{
private:
Car ch;
public:
Auto(int a) : Car(a)
{
//Car test(5);
}
};
int main()
{
Auto at(5);
return 0;
}
After referring below links :-
create objects in object passing variables through constructor
http://www.cplusplus.com/forum/beginner/9746/
I tried to write the same and execute it.unfortunately I am getting following compiler error :-
check.cpp: In constructor ‘Auto::Auto(int)’:
check.cpp:44: error: type ‘Car’ is not a direct base of ‘Auto’
If solution mentioned in the given links are correct then what wrong in my code ? My next query is ...why only parametrized constructor() throws compiler if try to initialize it without using initialization list.
This will throw compiler error :-
class Auto
{
private:
Car ch(5);
public:
Auto(int a)
{
}
};
But this does not :-
class Auto
{
private:
Car ch;
public:
Auto(int a)
{
}
};
Please help me in understanding this behaviour.
Thanks in advance.
In your example you are specifying by your constructor Auto(int a) : Car(a) that Auto is derived from Car, and that's what the compiler complains about.
To initialize your Car object (inside of Auto), do this Auto(int a) : ch(a). You put the type instead of the member's name.
About your second question, in-class member initialization is a new feature brought by C++11. You may use it by adding the parameter -std=c++11 to your compiler (GCC or Clang, msvc doesn't support it). See this question. In your case you can use it as chris pointed out :
class Auto {
// ...
Car ch{5};
int someVal = 5;
// ...
};
I am going through Chapter 17 in the new Stroustrup book and I am confused by initializing a class with an initialization list.
Example:
in .hpp:
class A
{
public:
A() : _plantName(std::string s), _growTimeMinutes(int 1);
virtual ~A();
private:
std::string _plantName;
int _growTimeMinutes;
};
in .cpp:
A::A() : _plantName(std::string s), _growTimeMinutes(int i)
{
}
or is it in .cpp:
A::A(std::string s, int i) : _plantName(std::string s), _growTimeMinutes(int i)
{
}
and calling that:
A a {"Carrot", 10};
I learned c++ back in 1998 and have only programmed in it off and on over the years until recently. How long ago did this stuff change? I know I could still do that the older way but I really want to learn new!
First I think initialization lists are useful when when you are dealing with constant members or when passing objects as parameters since you avoid calling the default constructor then the actual assignement.
You should write the following code in your cpp file : no need to rewrite the parameters types in the initialization list.
A::A(std::string s, int i) : _plantName(s), _growTimeMinutes(i)
{
}
Your h file should be :
class A
{
public:
A(std::string, int);
private:
std::string _plantName;
int _growTimeMinutes;
};
And you should create a new A object like that
A new_object("string", 12);
It should be
A::A(std::string s, int i) : _plantName(s), _growTimeMinutes(i) {
}
for example
supposing the variables _plantName and _growTimeMinutes are declared within class A or one of its superclasses. s and i are the constructor parameters for class A, the initialization will then call the string-constructor for _plantName with argument s and the int-constructor for _growTimeMinutes with argument i, thus initializing both variables.
Initialization lists are especially needed if you want to initialize const references. The assignment within a constructor would not work.
Hope I could help