Shared pointer from static function

235 Views Asked by At

I am trying to improve my coding by using smart pointers, and am currently trying to replace all old raw pointers in our legacy code-base at work with smart pointers (std::unique_ptr & std::shared_ptr). I now have a case where a pointer is returned from a static function.

What will happen if I change this to a std::shared_ptr that will be created using std::make_shared and returned from the function?

Will the ref-count be able to reach 0 since one reference is stored inside the static function, or will it remain until the program exits?

Previous:

static MyObject* MyClass::createPointer()
{
    return new MyObject();
}

Now:

static std::shared_ptr<MyObject> MyClass::createSharedPointer()
{
    return std::make_shared<MyObject>();
}
2

There are 2 best solutions below

1
Jakkapong Rattananen On BEST ANSWER

Don't worry. Modern C++ compiler will do copy elision following your code pattern. It doesn't matter if it is a static function or not.

But for std::shared_ptr, it's required to assign it to something or ref-count will be 0 (destructing the object immediately).

#include <memory>
#include <iostream>
struct MyObject
{
    MyObject(int i):member{i}{

    }
    ~MyObject(){
        std::cout << "MyObject#" << member << " destruct\n";
    }

    static std::shared_ptr<MyObject> createPointer(int i){
        return std::make_shared<MyObject>(i);
    }
    int member = 0;

   
};

static std::shared_ptr<MyObject> get_singleton_ptr(){
    static auto ptr = std::make_shared<MyObject>(3);
    return ptr;
}

MyObject& get_singleton_ref(){
    static auto ptr = std::make_unique<MyObject>(4);
    return *ptr;
}

int main() {
    MyObject::createPointer(1);

    auto ptr = MyObject::createPointer(2);

    get_singleton_ptr();

    get_singleton_ref();

    std::cout << "end program/scope\n";
}

The result should be

MyObject#1 destruct
end program/scope
MyObject#2 destruct
MyObject#4 destruct
MyObject#3 destruct
10
Chukwujiobi Canon On

In the old code, there is a memory leak on the following condition:

static MyObject* MyClass::createPointer()
{
    return new MyObject(); /* <—- memory leak */
}

Do you eventually delete the MyObject you created? If the program ends and you don’t, then there will be a memory leak. It is not a static variable but a dynamic one so you are responsible for deleteing.

In my mind it will not be cleaned up until the program exits

In the old code, it will not even be cleaned up until you clean it yourself.

In the new code:

static std::shared_ptr<MyObject> MyClass::createSharedPointer()
{
    return std::make_shared<MyObject>();
}

The smart pointer will handle deleteion for you so this is safe.

Will the ref-count be able to reach 0 since one reference is stored inside the static function, or will it remain until the program exits?

There is no reference stored inside the static function. The static function doesn’t do anything differently from a non-static function in this case.

A function itself does not keep a reference count on the std::shared_ptr it creates. It is the std::shared_ptr that does this and this is an implementation detail.