类成员唯一指针与自定义删除器外部初始化列表

时间:2016-03-02 13:05:26

标签: c++ smart-pointers unique-ptr

class foo {
    foo();
    unique_ptr<T, (void *)(T*)> ptr;
};

foo::foo() {
    bool x = some operation;
    if (!x) throw;
    ptr = unique_ptr<T, (void *)(T*)>(new T(x), deleter);
}

此代码无法编译,因为唯一指针及其删除器初始化为null(因为我没有在初始化程序列表中初始化它)。我无法在列表中初始化它,因为它依赖于变量x,如上所示。我怎样才能解决这个僵局?

3 个答案:

答案 0 :(得分:4)

试试这个:

foo()
: ptr(nullptr, deleter)
{
    if (!some operation) { throw AppropriateException(); }
    ptr.reset(new T(true));
}

答案 1 :(得分:1)

一种解决方案是添加一个静态函数来确定x应该是什么,然后将其返回到成员初始化列表中unique_ptr的构造函数

foo() : ptr(construct_t(), deleter) {}
static T* construct_t()
{
    bool x = some operation;
    if(!x) throw;
    return new T(x);
}

答案 2 :(得分:1)

使用生成器和自定义删除器的工作示例:

#include <iostream>
#include <memory>
#include <vector>

struct bar {};

struct bar_deleter {
    void operator()(bar* p) const noexcept {

        try {
            if (p) {
                std::cout << "deleting p" << std::endl;
            }
            else {
                std::cout << "not deleting p" << std::endl;
            }
        }
        catch(...) {
        }
    }
};

bool some_condition()
{
    static int counter = 0;
    return (counter++ % 2) == 0;
}

struct foo {
    using ptr_type = std::unique_ptr<bar, bar_deleter>;

    foo()
    : ptr(bar_generator())
    {}

    static ptr_type bar_generator() {
        if (some_condition()) {
            std::cout << "creating bar" << std::endl;
            return { new bar, bar_deleter{} };
        }
        else {
            std::cout << "not creating bar" << std::endl;
            return { nullptr, bar_deleter{} };
        }
    }

    ptr_type ptr;
};

int main()
{
    using namespace std;
    auto v = std::vector<foo>(10);
    return 0;
}

预期结果:

creating bar
not creating bar
creating bar
not creating bar
creating bar
not creating bar
creating bar
not creating bar
creating bar
not creating bar
deleting p
deleting p
deleting p
deleting p
deleting p