Reputation: 434
Let's say someString initialization is a tad complicated, hence we write a simple member function stringInitialization() with which to initialize someString in the body of the constructor:
class DemoL {
private:
int someNumber;
std::string someString;
void stringInitialization() {
if (someNumber == 1) {
someString = "FIRSTSTRING";
} else if (someNumber == 2) {
someString = "SECONDSTRING";
} else {
someString = "";
}
}
public:
explicit DemoL(int rNumber) :
someNumber(rNumber) {
stringInitialization();
}
};
This way, I'd assume, someString will be default initialized before the body of the constructor and only after that will it be modified by calling stringInitialization().
So, let's modify the code a bit, so that we initialize someString in the constructor initializer list:
class DemoL {
private:
int someNumber;
std::string someString;
std::string stringInitialization() const {
if (someNumber == 1) {
return "FIRSTSTRING";
} else if (someNumber == 2) {
return "SECONDSTRING";
} else {
return "";
}
}
public:
explicit DemoL(int rNumber) :
someNumber(rNumber),
someString(stringInitialization()) {}
};
Would you be so kind as to tell me whether the second variant is more efficient and correct?
Upvotes: 2
Views: 196
Reputation: 28384
Your assumption is correct. The constructor DemoL(int rNumber)
needs to be able to default construct the member someString
and this is no problem because std::string
is default constructible.
One obvious point is that one member could be not default-constructible, in which case you would have to initialize it.
But even if it is, default constructing it could be a waste of resources, if you are changing it right after, so the second alternative seems better to me as it goes straight to the point.
However, since , no, this is actually a bad idea, as pointed out in the comments.stringInitialization
returns by value, I would use std::move
So as a conclusion:
someNumber
someString
("calls" std::basic_string<...>::basic_string
) and then assigns it (calls std::basic_string<...>::operator=
)std::string
value from the sting literals when the call to stringInitialization
returns (calls basic_string<...>::basic_string(const char*)
), and then copy-constructs someString
(calls basic_string<...>::basic_string(basic_string&&)
); actually copy elision happens because stringInitialization
returns an rvalue.Upvotes: 1