在单个(成员)函数的范围之外应用 RAII

Applying RAII outside the scope of a single (member) function

本文关键字:范围 应用 RAII 函数 单个 成员      更新时间:2023-10-16

我有一个单例"管理器"对象,它在进程启动时实例化,并在进程期间(有效)存在。

此对象在其

生命周期内使用"new"创建多个临时任务(它们本身就是对象),然后使用"删除"销毁它们。 这两个操作在两个不同的函数中执行 - 一个函数由外部对象调用以执行特定任务,另一个函数是在任务完成时调用的回调,因此任务对象随后被销毁。

由于任务对象不是在"临时"范围(例如单个成员函数)中创建/销毁的,因此我是否浪费时间尝试在这种情况下应用 RAII? 或者我应该使用一种机制来处理这个问题?

问候理查。

您可以使用智能指针(例如shared_ptr)。单例应该保存指向这些任务的指针容器(例如映射),并在完成后将其从向量中删除。

例如(不是编译,只是为了说明):

class MySingleton
{
    typedef std::shared_ptr<Task> TaskPtr;
    std::map<int, TaskPtr> m_tasks;
    StartTask()
    {
        TaskPtr task = std::make_shared<Task>();
        m_tasks[index] = task;
        ...
    }
    OnTaskEnd()
    {
        TaskPtr task = m_tasks[index];
        m_tasks.remove(index);
        taskCompletedHandler(task);
        // Unless taskCompletedHandler copies task, it will be destroyed when this leaves scope.
    }

指向子任务的指针存储在第一个创建函数和第二个销毁函数之间。

将该指针更改为unique_ptr,它将反映它拥有资源生存期的事实。 使用类型记录所有权,防止资源句柄重复,并使代码更安全。

更先进的技术是用RAII完全取代"返回资源"阶段。 从 crearion 函数返回对某个 dqta 或令牌的unique_ptr,该函数在reset时隐式调用销毁函数:将 RAII 推上一个抽象级别。 Rhis并不总是容易,可取或有用,但仍然值得考虑。