Reputation: 10116
What I'm trying do?
I am trying to get user input in the default constructor of the object and compare it in the copy constructor if the previous object and the current object have the same brand name.
What is the problem?
I am not able to call the default and copy constructor of the same object.
My Code:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
class Scooty {
int cc ;
string model, brand;
bool goodBrands();
public:
Scooty () : cc(0), model(""), brand("") {
cout << "\n Enter the following scooty details: \n\n";
cout << "\n \t Brand: ";
cin >> brand;
transform(brand.begin(), brand.end(), brand.begin(), :: tolower);
cout << "\n \t Model: ";
cin >> model;
transform(model.begin(), model.end(), model.begin(), :: tolower);
cout << "\n \t CC: ";
cin >> cc;
}
Scooty (Scooty &s) { if (brand == s.brand) cout << "You will get a discount!\n"; }
void computeDataAndPrint ();
};
bool Scooty :: goodBrands() {
if (brand == "honda" || brand == "tvs" || brand == "yamaha")
return true;
return false;
}
void Scooty :: computeDataAndPrint () {
if (cc > 109 && goodBrands())
cout << "\n Good Choice!\n";
else
cout << "\n Its okay!\n";
}
int main() {
Scooty s;
Scooty s1, s1(s) // This gives error
s.computeDataAndPrint();
return 0;
}
Upvotes: 3
Views: 1709
Reputation: 3233
In your main() function:
`Scooty s; ` you create a variable `s` <br/>
Scooty s1, s1(s)
// You create a variable, s1
, and now you are trying to make another variable of the same name. That's an error
Try:
Scooty s, s1;
S1 = Scooty(s)
I hope you got an idea of how to do it.
Correct program or at least working...
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
class Scooty {
int cc ;
string model, brand;
bool goodBrands();
public:
Scooty () {
cc = 0, brand = "", model = "";
cout << "\n Enter the following scooty details: \n\n";
cout << "\n \t Brand: ";
cin >> brand;
transform(brand.begin(), brand.end(), brand.begin(), :: tolower); //STRING LOWER FUNCTION ..
cout << "\n \t Model: ";
cin >> model;
transform(model.begin(), model.end(), model.begin(), :: tolower); //STRING LOWER FUNCTION ..
cout << "\n \t CC: ";
cin >> cc;
}
Scooty (Scooty &s) : Scooty() { //Initializing the object first then comparing, [using two constructors]
if (brand == s.brand) cout << "You will get a discount!\n";
}
void computeDataAndPrint ();
};
bool Scooty :: goodBrands() {
if (brand == "honda" || brand == "tvs" || brand == "yamaha")
return true;
return false;
}
void Scooty :: computeDataAndPrint () {
if (cc > 109 && goodBrands())
cout << "\n Good Choice!\n";
else
cout << "\n Its okay!\n";
}
int main() {
Scooty s; // Calling default constructor for constructor of S.
// s.computeDataAndPrint();
Scooty s1(s); // Calling copy constructor which firstly calls the default constructor then executes the copy constructors body.
return 0;
}
This program is logically incorrect due to fact that it is violating the rule of what the copy constructor is for. The copy constructor should be used to copy one object into another, and for such an operation you should overload the ==
operator.
Upvotes: 2
Reputation: 596352
C++11 introduces the concept of delegating constructors. A constructor can call another constructor of the same class in its own initialization list. For example:
Scooty (const Scooty &s)
: Scooty() // <-- add this
{
if (brand == s.brand)
cout << "You will get a discount!\n";
}
This allows a constructor to leverage the initialization(s) performed by another constructor of the same class.
In earlier versions of C++, the initialization list can only call the constructor of immediate base class(es) and data members, so common initializations must be performed in a separate function/method that the constructor bodies can call as needed. For example:
class Scooty {
int cc;
string model;
string brand;
void init() {
cout << "\n Enter the following scooty details:- \n\n";
cout << "\n \t Brand:";
cin >> brand;
transform(brand.begin(), brand.end(), brand.begin(), ::tolower);
cout << "\n \t Model:";
cin >> model;
transform(model.begin(), model.end(), model.begin(), ::tolower);
cout << "\n \t CC:";
cin >> cc;
}
...
public:
Scooty () : cc(0) {
init(); // <-- here
}
Scooty (const Scooty &s) : cc(0) {
init(); // <-- here
if (brand == s.brand)
cout << "You will get a discount!\n";
}
...
};
int main() {
Scooty s;
Scooty s1(s);
...
return 0;
}
Upvotes: 3
Reputation: 5468
A constructor simply initializes an instance into a valid state. First of all, you didn't ask about this but I would modify your default constructor to simply take the cc, model, and brand, and move all of the I/O into a separate function:
class Scooty {
// etc...
public:
// default constructor
Scooty (int cc, string model, string brand) : cc(cc), model(model), brand(brand) {}
// a correctly-written copy constructor (not necessary since the implicit copy constructor does exactly this)
Scooty (const Scooty &s) : cc(s.cc), model(s.model), brand(s.brand) {}
// etc...
};
Scooty getScootyFromUserInput() {
int cc;
string brand, model;
cout << "\n Enter the following scooty details:- \n\n";
cout << "\n \t Brand:";
cin >> brand;
transform(brand.begin(),brand.end(), brand.begin(), :: tolower);
cout << "\n \t Model:";
cin >> model;
transform(model.begin(),model.end(), model.begin(), :: tolower);
cout << "\n \t CC:";
cin >> cc;
return Scooty(cc, brand, model);
}
Your if (brand == s.brand)
statement certainly doesn't belong in the copy constructor - when you create a copy, the brands will always of course be the same. What you should do is turn that into a helper function, or a class method to check if the discount applies:
class Scooty {
public:
bool checkDiscount(const Scooty &) const;
}
bool Scooty::checkDiscout(const Scooty &scooty) const {
return brand == scooty2.brand;
}
And write your main function like this:
int main() {
Scooty s = getScootyFromUserInput();
Scooty s1 = getScootyFromUserInput();
if (s.checkDiscout(s1)) {
cout << "You will get a discount!\n";
}
}
Upvotes: 1