Can I specify default values at once like in METHOD 1 or should I use overloaded constructor like in METHOD 2 or with initialization list like in METHOD 3/4?
Which method is better/right way and why (all of them seems to work)?
And what is the difference between METHOD 3 and 4 - should I specify first constructor declaration, and then next definition outside class or can I at once specify definition?
METHOD 1:
#include <iostream>
#include <string>
using namespace std;
const string GLOBAL_VAR = "XXX";
class Object
{
private:
string var;
public:
Object(string inArg = "yyy")
{
this->var = GLOBAL_VAR + inArg + "ZZZ";
}
string show()
{
return this->var;
}
};
int main() {
Object o1, o2("www");
cout << o1.show() << endl;
cout << o2.show() << endl;
system("pause");
}
METHOD 2:
#include <iostream>
#include <string>
using namespace std;
const string GLOBAL_VAR = "XXX";
class Object
{
private:
string var;
public:
Object()
{
this->var = GLOBAL_VAR + "yyyZZZ";
}
Object(string inArg)
{
this->var = GLOBAL_VAR + inArg + "ZZZ";
}
string show()
{
return this->var;
}
};
int main() {
Object o1, o2("www");
cout << o1.show() << endl;
cout << o2.show() << endl;
system("pause");
}
METHOD 3:
#include <iostream>
#include <string>
using namespace std;
const string GLOBAL_VAR = "XXX";
class Object
{
private:
string var;
public:
//declaration:
Object();
Object(string);
string show()
{
return this->var;
}
};
//definition:
Object::Object() : var(GLOBAL_VAR + "yyyZZZ") {}
Object::Object(string inArg) : var(GLOBAL_VAR + inArg + "ZZZ"){}
int main() {
Object o1, o2("www");
cout << o1.show() << endl;
cout << o2.show() << endl;
system("pause");
}
METHOD 4:
#include <iostream>
#include <string>
using namespace std;
const string GLOBAL_VAR = "XXX";
class Object
{
private:
string var;
public:
//declaration and definition in one:
Object() : var(GLOBAL_VAR + "yyyZZZ") {}
Object(string inArg) : var(GLOBAL_VAR + inArg + "ZZZ") {}
string show()
{
return this->var;
}
};
int main() {
Object o1, o2("www");
cout << o1.show() << endl;
cout << o2.show() << endl;
system("pause");
}
I consider both approaches to be equally valid. Depending on the particulars of each individual class, each approach has its advantages, strengths, and weaknesses.
Using a default value would typically be the best choice when the object needs to be initialized pretty much the same way, whether or not the constructor parameter gets defaulted. Specifying a default value prevents the need to duplicate a bunch of code. You only have one constructor.
On the other hand, using overloaded constructors makes it possible to cleanly construct the object in completely different way, depending on whether the parameter is given or not. Forcing the class to have a single constructor typically results in carpetbombing the code with a bunch of if
statements, in this case.
Also, don't forget about the third option: a delegating constructor. Using the class in your example code:
Object() : Object("")
{
}
This approach has its own inherent advantages too.
There is no consensus on which approach is best, in general. It's best to consider the individual requirements of each class, and choose the approach that works best for that class. What's best for one class may not be the best way for another class.