RAII с std :: function - PullRequest
       90

RAII с std :: function

1 голос
/ 04 мая 2020

Является ли std :: function умным по своей природе, как std::shared_ptr и std::unique_ptr? Думаю, нет? У меня есть std::function, который является членом класса, как показано ниже.

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? 
    }
}

Вопрос:
Обязательно ли назначать nullptr на m_func в деструкторе? Или мне следует превратить m_func в умный указатель, выполнив что-то вроде ниже? Или это m_func умный по умолчанию и неявно следует 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
    }
}

1 Ответ

2 голосов
/ 04 мая 2020

std::function имеет деструктор, который удаляет все ресурсы, которыми он управлял, если они есть. Эта строка:

   m_func = nullptr; // Is this required? 

никогда не требуется. Деструкторы членов класса вызываются автоматически, и если нет, то присвоение nullptr никогда не будет «правильным». Если бы m_func был указателем, вы бы потеряли значение указателя и возможность удалить то, на что он указывает.

Немного странно, что в официальной документации по адресу ...

From cppreference на std::function s деструкторе не упоминается, что он умный :

Уничтожает экземпляр std :: function. Если std :: function не пуста, ее цель также уничтожается.

В целом можно с уверенностью предположить, что класс очищает любые ресурсы, которыми он управляет, в своем детрукторе, в противном случае он может считаться сломанным. Очистка ресурсов в деструкторах - это не что-то новое в интеллектуальных указателях. Интеллектуальные указатели применяют RAII, который всегда присутствует в C ++, только к указателям для инкапсуляции управления динамически выделяемой памятью.

...