I'm trying to create an object-configurator using a fluent interface. Code:
class Configurator {
public:
Configurator() {
printf("Constructor.\n");
}
~Configurator() {
printf("Destructor.\n");
printf("String: %s\n", this->str_.c_str());
}
Configurator& Append(const std::string& str) {
this->str_ += str;
return *this;
}
private:
std::string str_;
};
Configurator PrepareConfigurator() {
return Configurator();
}
Configurator PrepareWithSomeAppend() {
return PrepareConfigurator().Append("hello").Append(", ");
}
int main() {
printf("Start.\n");
PrepareWithSomeAppend().Append("world!");
printf("End.\n");
return 0;
}
Class Configurator
prints string only in destructor(I want to do so that I do not force to call a helper method to call an action). Append method appends the string to the private field string. Method PrepareConfigurator
creates Configurator
. Method PrepareWithSomeAppend
calls PrepareConfigurator
and calls Append
method and returns object from function. Further in main
I call Append
method again and I expect the output like that:
Start.
Constructor.
Destructor.
String: hello, world!
End.
But I get the output:
Start.
Constructor.
Destructor.
String: hello,
Destructor.
String: hello, world!
End.
Why does the destructor call twice? How can I prevent it? Thanks in advance!
Edit :
I also tried to create Configurator
in PrepareWithSomeAppend
and the problem isn't solved. Destructor calls twice.
Configurator PrepareWithSomeAppend() {
return Configurator().Append("hello").Append(", ");
}
Also, I tried to return a reference to Configurator
from PrepareWithSomeAppend
:
Configurator& PrepareWithSomeAppend() {
return Configurator().Append("hello").Append(", ");
}
And it doesn't work too, destructor calls in PrepareWithSomeAppend
method for the local object and I get segmentation fault error in main
function because of reference points to the destructed object. How can I prevent calling the destructor for a local object in PrepareWithSomeAppend
function? Or return an object without copying?
To me it looks like the reason for this is the PrepareConfigurator() method, because it creates a new Configurator object. However, we return a Configurator result as well. This mean that the constructed object is copied on return, and we destroy the locally constructed object as soon as we leave the PrepareConfigurator() method.
Try to change the method so that it returns a reference or a pointer.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.