I have created 3 classes: Auto (means "car"), Klant (means "customer") and AutoVerhuur (means "car dealership).
In my main(), I have created Auto and Klant objects, and am trying to create an AutoVerhuur object.
In this last class, I basically want to reference to a specifc Klant and Auto (which customer rented which car). But, when I try that, I get an error:
error: no matching function for call to 'Auto::Auto()'
How do I correctly reference other objects in my object?
Here is my code, if you want to take a look:
#include <iostream>
using namespace std;
class Auto{
private:
string type;
double prijs_per_dag;
public:
Auto(string type, double prijs_per_dag){
this->type = type;
this->prijs_per_dag = prijs_per_dag;
}
void set_prijs_per_dag(double percentage){
this->prijs_per_dag = percentage;
}
double get_prijs_per_dag(){
return prijs_per_dag;
}
};
class Klant{
private:
string naam;
double korting_percentage;
public:
Klant(string naam):
naam(naam){}
void set_korting(double percentage){
this->korting_percentage = percentage;
}
double get_korting(){
return this->korting_percentage;
}
string get_name(){
return naam;
}
void set_name(string naam){
this->naam = naam;
}
};
class AutoHuur{
private:
int aantal_dagen;
Auto wagen;
Klant huur;
public:
AutoHuur(Auto car, Klant huurder, int dagen){
wagen = car;
huur = huurder;
aantal_dagen = dagen;
}
};
int main(){
Klant k("Mijnheer de Vries");
k.set_korting(10.0);
Auto a1("Peugeot 207", 50);
AutoHuur ah1(a1, k, 4);
}
Your Auto class does not have a default constructor defined, but your AutoHuur class has an Auto wagen; data member which the compiler is trying to default-construct (because you haven't told it otherwise), hence the error.
So, you need to either:
give the Auto class a default constructor, eg:
Auto(){
this->type = "";
this->prijs_per_dag = 0;
// or whatever default values make sense for your needs...
}
Otherwise, change the constructor of the AutoHuur class to use its member initialization list to construct the wagen member using the desired Auto constructor (you should do the same for the other data members, too), eg:
AutoHuur(Auto car, Klant huurder, int dagen)
: wagen(car), huur(huurder), aantal_dagen(dagen)
{
}
Related
How to fix the function 'func' so that it returns the objects without being destroyed?
function 'func' must add the objects to a list and return them but be destroyed
The Smoothy abstract class has a purely virtual description method (). DecoratorSmoothy
contains a smoothy, description () and getPret () methods return the description and price
aggregate smoothy.
SmoothyCuFream and SmoothyCuUmbreluta classes add the text “cu crema”
respectively “cu umbreluta” in the description of the smoothy contained. The price of a smoothy that has the cream increases by 2 euro, the one with the umbrella costs an extra 3 euro.
BasicSmoothy class is a smoothy without cream and without umbrella, method
description () returns the name of the smothy
#include <iostream>
#include <vector>
using namespace std;
class Smoothy {
private:
int pret=0;
public:
virtual string descriere() = 0;
int getPret(){
return pret;
}
void setPret(int a) {
pret += a;
}
};
class BasicSmooty : public Smoothy {
private:
string nume;
public:
BasicSmooty(string n) :
nume { n } {}
string descriere() {
return nume;
}
};
class DecoratorSmoothy : public Smoothy {
private:
Smoothy* smooty;
public:
DecoratorSmoothy() = default;
DecoratorSmoothy(Smoothy* n) :
smooty{ n } {}
string descriere() {
return smooty->descriere();
}
int getPret() {
return smooty->getPret();
}
};
class SmootyCuFrisca : public DecoratorSmoothy {
private:
BasicSmooty bsc;
public:
SmootyCuFrisca(string desc) :
bsc{ desc } {}
string descriere() {
setPret(2);
return bsc.descriere() + " cu frisca ";
}
};
class SmootyCuUmbreluta : public DecoratorSmoothy{
private:
BasicSmooty bsc;
public:
SmootyCuUmbreluta(string desc) :
bsc{ desc } {}
string descriere() {
setPret(3);
return bsc.descriere() + " cu umbreluta ";
}
~SmootyCuUmbreluta() {
cout << "rip";
}
};
vector<Smoothy*> func(void)
{
std::vector<Smoothy*> l;
SmootyCuFrisca a1{ "smooty de kivi" };
SmootyCuUmbreluta a2{ "smooty de kivi" };
SmootyCuFrisca a3{ "smooty de capsuni" };
BasicSmooty a4{ "smooty simplu de kivi" };
l.push_back(&a1);
l.push_back(&a2);
l.push_back(&a3);
l.push_back(&a4);
return l;
}
int main() {
vector<Smoothy*> list;
// Here when i call func() objects are distroyed
list = func();
return 0;
}
In func you are storing the address of function local variables in l. So when you return l from the function, all the Smoothy* are now pointing to invalid memory.
To fix this, you can allocate memory for each pointer you add to l, like this:
l.push_back(new Smoothy{a1}); // instead of l.push_back(&a1);
// etc. for a2, a3, ...
To really get away from this problem, consider not using pointers at all. If your design doesn't need it, you can get rid of the pointers, and you'll save yourself a lot of trouble.
Well, when a method returns, of course all local/automatic variables are destroyed. Under the late revision c++ changes, there is the return && modifier, which invokes move semantics, which means for not const local/automatic objects you return, it steals: clones the returned object, making a new object and copying all the primitives and object pointers, then sets the object pointers to null so they cannot be deleted/freed by the destructor. (Note that C free of a null pointer does nothing!) For const, of course, it must deep copy.
Please I am trying to print out the value of a nested class from the private access specifier.
#include <iostream>
#include <cstdlib>
using namespace std;
class cal{
private:
int a = 0;
public:
int setNum(int m){
a = m;
}
void getNum(){
cout<<"the number is: "<<a<<endl;
}
class area{
public:
int setMan(int z){
cal obj;
obj.setNum(z);
return 1;
}
};
};
int main(){
cal::area obj2;
obj2.setMan(200);
cal obj3;
obj3.getNum();
'
return 0;
}
cal::area obj2;
obj2.setMan(200); is to set 200 to the nested class area and into the function setMan, of which setMan which pass the same value to the int setNum(int m){a = m;} this will set the value of a to "200". Then I wanted to print out the value of a but it displays 0 instead of 200.
Defining a nested class only provides a definition for a nested class. If you want to have a member of that class you have to declare it:
struct cal {
struct area {}; // class definition
area m_area; // member
};
int setMan(int z){
cal obj;
obj.setNum(z);
return 1;
}
The object obj is a temporary auto object and would be destroyed when you return from the function. By the way, "set" functions should not return values, returning 1 is confusing.
If you wish to connect objects somehow consider the composition or aggregation. For example:
// ...
class area{
public:
area(cal& obj) : obj(obj);
int setMan(int z){
obj.setNum(z);
return 1;
}
cal &obj;
};
// ...
int main(){
cal obj;
cal::area obj2(obj);
obj2.setMan(200);
obj.getNum();
return 0;
}
Anyway, that is just an artificial example, I don't see the reason you make area a nested class, the reason of setting values to cal from area, etc.
I have recently started learning OOP in C++ and I started solving example tasks regarding it. I want to instantiate an object of the class CStudent after having created a default constructor for it. However the compiler cannot compile the code. I would like to ask why is that?
When you write inside your class:
CStudent();
CStudent(string name, string fn);
...you only declare two constructors, one default (taking no-argument) and one taking two strings.
After declaring them, you need to define them, the same way you defined the methods getName or getAverage:
// Outside of the declaration of the class
CStudent::CStudent() { }
// Use member initializer list if you can
CStudent::CStudent(std::string name, string fn) :
name(std::move(name)), fn(std::move(fn)) { }
In C++, you can also define these when declaring them inside the class:
class CStudent {
// ...
public:
CStudent() { }
CStudent(std::string name, string fn) :
name(std::move(name)), fn(std::move(fn)) { }
// ...
};
Since C++11, you can let the compiler generate the default constructor for you:
// Inside the class declaration
CStudent() = default;
This should work, As commented by Holt, You need to define constructor, You have just declared it.
#include <iostream>
#include <string>
#include <list>
using namespace std;
class CStudent {
string name = "Steve";
list<int> scores;
string fn;
public:
CStudent() {};
CStudent(string name, string fn);
string getName();
double getAverage();
void addScore(int);
};
string CStudent::getName() {
return name;
}
double CStudent::getAverage() {
int av = 0;
for (auto x = scores.begin(); x != scores.end(); x++) {
av += *x;
}
return av / scores.size();
}
void CStudent::addScore(int sc) {
scores.push_back(sc);
}
int main()
{
CStudent stud1;
cout<< stud1.getName()<< endl;
return 0;
}
Here is the problem:
Write three base class named Voltmeter, Ammeter and ResistanceMeter.
Voltmeter class will have a member function volt, a non default constructor, a copy constructor
and a function measureVolt().
Ammeter class will have a member function amp, non default constructor, a copy constructor and
a function measureCurrent().
ResistanceMeter class will have a member function resistance, non default constructor,
a copy constructor and a function measureResistance().
Now write a class Multimeter which will
have object of Voltmeter, Ammeter and ResistanceMeter so thus it can use the functionality of those class.
In my solution, the compiler say undefined reference on every object I used in the class 'multimeter'. Code is as below:
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
class voltmeter{ //class - Voltmeter
float volt;
public:
voltmeter(); //default constructor
voltmeter(float v){ //non default constructor
volt = v;
}
voltmeter(voltmeter &ob) //copy constructor
{
volt = ob.volt;
}
void set_volt(float v)
{
volt = v;
}
float get_volt(void)
{
return volt;
}
void measure_volt(void) //measureVolt()
{
cout<<"Current volt in the circuit is: "<<volt<<"V"<<endl;
}
};
class ameter
{
float amp;
public:
ameter();
ameter(float a)
{
amp = a;
}
ameter(ameter &ob)
{
amp = ob.amp;
}
void measure_current(void)
{
cout<<"Current flow in circuit is: "<<amp<<"amp"<<endl;
}
void set_amp(float a)
{
amp = a;
}
float get_amp(void)
{
return amp;
}
};
class res_meter //class - resistanceMeter
{
float resistance;
public:
res_meter();
res_meter(float res)
{
resistance = res;
}
res_meter(res_meter &ob)
{
resistance = ob.resistance;
}
float get_resistance(void)
{
return resistance;
}
void set_resistance(float res)
{
resistance = res;
}
void meas_res(void)
{
cout<<"Current resistance in circuit is "<<resistance<<"ohm"<<endl;
}
};
class multimeter
{
res_meter r1;
ameter a1;
voltmeter v1;
public:
multimeter(){
r1.set_resistance(12.30);
a1.set_amp(22.5);
v1.set_volt(26.9);
}
// ~multimeter();
void show_info(void)
{
cout<<"Current Multimeter Status is as below: "<<endl;
a1.measure_current();
r1.meas_res();
v1.measure_volt();
}
};
int main()
{
multimeter M;
M.show_info();
return 0;
}
You declare a default constructor for all the classes (which is used in the multimeter class), but you never define the constructors.
Change e.g.:
class voltmeter
{
// ...
voltmeter();
// ...
};
to
class voltmeter
{
// ...
voltmeter() {}
// ...
};
In my solution, the compiler say undefined reference on every object I used in the class 'multimeter'.
Read your warning messages more carefully. The compiler is telling you that the multimeter default constructor (which is defined) is referencing the default constructors for classes ameter, res_meter, and voltmeter'. It is those default constructors that aren't defined.
So define them, or use the non-default constructors that you did define.
Im trying to get this program to take the users input and put that into a public function and assign it to the privateVariable, then I want it to return the value of privateVariable to main() and output it to the screen, but all it displays is the value of an undefined int ( -858993460 ). What logical problem am I having here ?
#include <iostream>
#include <string>
using namespace std;
class MyClass
{
private:
int privateVariable;
public:
int userVariable;
void setVariable(int userVariable)
{
privateVariable = userVariable;
}
int getVariable()
{
return privateVariable;
}
};
int main()
{
int userVariable;
cin >> userVariable;
MyClass object1;
MyClass object2;
object1.setVariable(userVariable);
object2.getVariable();
cout << object2.getVariable();
system("PAUSE");
return 0;
}
You are setting in object1 and getting from object2. object1 and object2 are different objects. As variable in object2 is not set, you get a garbage value.
And I see no use of public userVariable in MyClass.
You are not setting the variable. You call setVariable on object1 and getVariable on object2, so the member of object1 remains uninitialized.
object1.setVariable(5); // object1.privateVariable = 5
// object2.privateVariable -> still uninitialized
object2.getVariable(); // returns uninitialized variable
For this to work, depending on what you want:
class MyClass
{
private:
static int privateVariable;
//......
}
This way, privateVariable will be a class-scoped member, not instance-scoped. That means it has the same value for all instances of the class (and even if instances were not created). This also means you can make both your functions static:
class MyClass
{
private:
static int privateVariable;
public:
static void setVariable(int userVariable)
{
privateVariable = userVariable;
}
static int getVariable()
{
return privateVariable;
}
};
and you can call the methods without instances:
MyClass::setVariable(5); //MyClass.privateVariable = 5;
MyClass::getVariable(); //returns 5
object1.getVariable(); //returns also 5
Another option is, if you don't want static members, to set the member for both objects:
object1.setVariable(5); // object1.privateVariable = 5
// object2.privateVariable -> still uninitialized
object2.setVariable(5); //object2.privateVariable = 5
object2.getVariable(); // returns 5
Or, you could define a constructor and set the variable there:
class MyClass
{
private:
static int privateVariable;
//......
public:
MyClass()
{
privateVariable = 5;
}
}
With this, every object you create will have the member initialized to 5.
object2 does not have your variable initialized as you set it on object1, the code you posted would only work if privateVariable was static.