Hello I'm already learning CPP and want to set a default value for child class but I don't know were to set it, I try many things and don't found information on internet. I'm looking for do less constructors ass possible.
I want to set by default the string arm by def0 when no paramters are set
class Parts {
private:
std::string _serial;
bool _functionnal;
public:
Parts(std::string &serial, bool functional);
std::string serial();
};
class Arms : public Parts {
private:
std::string _serial = "def0";
public:
Arms(std::string &serial, bool functionnal = true) : Parts(serial, functionnal)
{
}
};
Parts::Parts(std::string &serial, bool functional)
{
this->_serial = serial;
this->_functionnal = functional;
std::cout << "Name set to: " << serial << std::endl;
}
int main()
{
std::string sample = "sample";
Arms Ex(sample, false);
Arms setAsDefault();
return 0;
}
You already have the basis for using default parameters in place, however you are missing one crucial detail: you need to make the string& a const reference (otherwise you cannot assign it a default value)!
This requires you to change the constructor of Parts (both declaration and definition) to:
Parts(const std::string &serial, bool functional)
And change the Arms class to:
class Arms : public Parts {
public:
Arms(const std::string &serial = "def0", bool functionnal = true) : Parts(serial, functionnal)
{
}
};
One more detail is that Arms setAsDefault(); does not create a new object, it instead declares a function returning an Arms (this is known as the most vexing parse problem: https://en.wikipedia.org/wiki/Most_vexing_parse)
Instead you need to change it to Arms setAsDefault;
EDIT: In fact you can simplify the constructor of Parts by using member initializer lists, which will also prevent a default string construction (as pointed out by user4581301), e.g.:
Parts::Parts(const std::string &serial, bool functional) : _serial(serial), _functionnal(functional)
{
std::cout << "Name set to: " << serial << std::endl;
}
So your example changed to do what you wanted is the following code
#include <string>
#include <iostream>
class Parts {
private:
std::string _serial;
bool _functionnal;
public:
Parts(const std::string &serial, bool functional);
std::string serial();
};
class Arms : public Parts {
public:
Arms(const std::string &serial = "def0", bool functionnal = true) : Parts(serial, functionnal)
{
}
};
Parts::Parts(const std::string &serial, bool functional) : _serial(serial), _functionnal(functional)
{
std::cout << "Name set to: " << serial << std::endl;
}
int main()
{
std::string sample = "sample";
Arms Ex(sample, false);
Arms setAsDefault;
return 0;
}
In order to have a constructor that takes only a bool (as asked in the comments) you need to provide another overload for the constructor, e.g. (using C++11 delegating constructors):
Arms(bool functionnal) : Arms("def0", functionnal) {}
EDIT2: As suggested by SergeyA an even better option is to pass the parameters by value and using std::move to move-construct the member variables. In this case your classes look like this:
class Parts {
private:
std::string _serial;
bool _functionnal;
public:
Parts(std::string serial, bool functional);
std::string serial();
};
class Arms : public Parts {
public:
Arms(std::string serial = "def0", bool functionnal = true) : Parts(std::move(serial), functionnal)
{
}
Arms(bool functionnal) : Arms("def0", functionnal) {}
};
Parts::Parts(std::string serial, bool functional) : _serial(std::move(serial)), _functionnal(functional)
{
// Note that `serial` will be empty after the move
// so you need to access the member variable instead
std::cout << "Name set to: " << _serial << std::endl;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With