jeudi 13 janvier 2022

Class with no destructor returns copy of object but when I add a destructor it returns the same object

I was playing around with classes in C++, specifically implementing a private constructor with a static "create" function that returns the object.

// main.cpp
#include <iostream>

class Foo {
public:
    static Foo create_foo() {    
        Foo foo{};
        std::cout << "Foo::create_foo():: Address of foo: " << &foo << std::endl;

        return foo;
    }
private:
    Foo() { std::cout << "Foo::Foo():: Constructor" << std::endl; }
};

int main() {
    auto foo = Foo::create_foo();
    std::cout << "main():: Address of foo: " << &foo << std::endl;
    
    return 0;
}

Running the code above creates two different Foo objects: one in Foo::create_foo() and one in main() as seen from the output:

Foo::Foo():: Constructor
Foo::create_foo():: Address of foo: 0x7ffe5d5e60bf
main():: Address of foo: 0x7ffe5d5e60ef

My first inclination was "okay, it's calling the copy constructor." So I added the following public copy constructor:

Foo(Foo const&) { std::cout << "Foo::Foo(Foo const&):: Copy constructor" << std::endl; }

This is where my confusion lies, by simply adding a copy constructor, Foo::create_foo() and main() now contain the same object:

Foo::Foo():: Constructor
Foo::create_foo():: Address of foo: 0x7ffe53c9d63f
main():: Address of foo: 0x7ffe53c9d63f

This same behavior happens as well if I add a public destructor:

~Foo() { std::cout << "Foo::~Foo():: Destructor" << std::endl; }

Output:

Foo::Foo():: Constructor
Foo::create_foo():: Address of foo: 0x7ffed84a400f
main():: Address of foo: 0x7ffed84a400f
Foo::~Foo():: Destructor

I am just curious as to why adding an additional (copy) constructor or destructor changes the behavior of my static function. Could it be some compiler optimization? I am using gcc version 10.2.1 20201125 (Red Hat 10.2.1-9) (GCC) and compiling without any flags (g++ -o main main.cpp).

Aucun commentaire:

Enregistrer un commentaire