懒惰地重新创建其资源的智能指针

Net*_*ire 5 c++ pointers smart-pointers object-lifetime

我有一个ServiceProvider类,其中包含几个指向不同服务的指针,如:

class ServiceProvider()
{
    Service3* GetService3();

public:
    void Process(Object* o);
    void Shrink();

private:
    TAutoSpawningPtr<Service1> service1;
    TAutoSpawningPtr<Service2> service2;

    Service3* service3;
}
Run Code Online (Sandbox Code Playgroud)

注意,这TAutoSpawningPtr是一个理论上的智能指针?lass我正在寻找,而service3被声明为一个普通的指针,以明确显示我需要的行为.身体Process():

void ServiceProvider::Process(Object* o)
{
    service1->Process(o);
    service2->Process(o);
    GetService3()->Process(o);
}
Run Code Online (Sandbox Code Playgroud)

身体GetService3():

void ServiceProvider::GetService3()
{
    if(!service3)
    {
       service3 = new Service3();
    }

    return service3;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,Service3正在创建一个懒惰的实例,并且在需要之前它不存在.

Shrink()定期调用方法以删除所有内部服务.像这样:

void ServiceProvider::Shrink()
{
    service1.Release(); // delete its internal Service1 pointer if it exists.
    service2.Release(); // delete its internal Service2 pointer if it exists.

    if (service3)
    {
        // delete its internal Service3 pointer if it exists.
        delete service3;
        service3 = nullptr;
    }
}
Run Code Online (Sandbox Code Playgroud)

我需要什么:我想TAutoSpawningPtr<>成为一个智能指针类,一旦我使用重载取消引用指针,它就会通过调用默认的construcror 来自动创建它的类实例operator->.一旦调用该Release()方法,必须删除由指针引起的内部资源(当然,当我再次需要它时,必须重新创建它).

我为什么需要这个?

  1. 自动控制对象的存在/不存在.
  2. 直接(如this->service3->Process(o))取代指针而不是间接取消指针时防止nullptrs GetService3().
  3. 无需显式检查即可释放未使用的服务

问题是:标准(或任何第三方)库是否具有满足我需求的自动指针类?如果没有,你会不会给我带来一些显示我需要的行为的代码示例.谢谢.

Cur*_*ous 5

这里最简单的解决方案是调用一个函数,如果它们未初始化或者没有指向任何东西,则初始化它们.

但是如果你真的想要,你可以创建一个简单的代理指针类来为你做这件事.例如

#include <iostream>
#include <memory>

using std::cout;
using std::endl;

class Something {
public:
    Something() {
        cout << __PRETTY_FUNCTION__ << endl;
    }
    void do_something() {
        cout << __PRETTY_FUNCTION__ << endl;
    }
};

template <typename Type,
          template <typename...> class Ptr = std::unique_ptr>
class AutoAllocatingPtr {
public:
    Type* operator->() {
        if (!this->ptr) {
            this->ptr = Ptr<Type>{new Type{}};
        }
        return this->ptr.get();
    }

    void release() {
        this->ptr.reset();
    }

private:
    Ptr<Type> ptr;
};

int main() {
    // default unique ownership with std::unique_ptr
    auto ptr = AutoAllocatingPtr<Something>{};
    ptr->do_something();
    ptr.release();
    ptr->do_something();

    // if you want shared ownership
    auto s_ptr = AutoAllocatingPtr<Something, std::shared_ptr>{};
    s_ptr->do_something();
    s_ptr.release();
    s_ptr->do_something();
}
Run Code Online (Sandbox Code Playgroud)

注意请注意最后的代码以及如何使用它来切换指针所显示的所有权语义类型.