简体   繁体   中英

Double destructor call in C++

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM