Search code examples
c++c++11smart-pointersstd-functionraii

RAII with std::function


Is std::function smart in nature like std::shared_ptr and std::unique_ptr? I guess no? I have a std::function which is a class member like below.

class MyClass {
    typedef std::function<void(void)> Func;
    Func m_func;

public:
    MyClass() {
        m_func = []() {
            std::cout << "Func called" << std::endl;
        }
    }

    ~MyClass() {
       m_func = nullptr; // Is this required? 
    }
}

Question:
Is it mandatory to assign nullptr to m_func in the destructor? Or should I make m_func into a smart pointer by doing something like below? Or is it that m_func is smart by default and implicitly follows RAII?

class MyClass {
    typedef std::function<void(void)> Func;
    std::unique_ptr<Func> m_func;

public:
    MyClass() {
        m_func = std::make_unique<Func>();
        *m_func = []() {
            std::cout << "Func called" << std::endl;
        }
    }

    ~MyClass() {
       // auto released
    }
}

Solution

  • std::function has a destructor that deletes any resources it managed, if there are any. This line:

       m_func = nullptr; // Is this required? 
    

    is never required. A class members destructors are called automatically and if not, assigning nullptr is never "the right" thing. If m_func was a pointer you would loose the pointers value and the ability to delete what it points to.

    A bit strange that it is not mentioned to be smart in official documentation at ...

    From cppreference on std::functions destructor:

    Destroys the std::function instance. If the std::function is not empty, its target is destroyed also.

    In general it is safe to assume that a class cleans up any resources it mangages in its detructor, otherwise it can be considered as broken. Cleaning up resources in destructors is not something that came new with smart pointers. Smart pointers only apply RAII wich was present in C++ always to pointers to encapsulate managment of dynamically allocated memory.