智能指针,用于管理生命周期,但也可以复制内存

时间:2015-01-09 00:39:34

标签: c++ c++11

在我的情况下,给定一个你想要具有递归字段的类:

class SemiVariant {

 union {
  std::pair<SemiVariant, SemiVariant> pair_value_;
  int something_else_;
 }
};

基本上这不可能是因为很明显我们的类型不完整。 使用unique_ptr管理内存并允许不完整类型也不起作用。我不知道是否已经有一个现有的类可以用作optional但是可以使用动态内存。 unique_ptr对我的情况并不完美,因为它们会禁用默认的复制构造函数。我希望存在。

1 个答案:

答案 0 :(得分:4)

您可以将自己的可自由扩展名编写为std::unique_ptr

template <class T>
class opaque_pointer : public std::unique_ptr < T >
{
public:
    // Simple construction by moving a uniqe_ptr into it.
    opaque_pointer(std::unique_ptr<T>&& rhs)
        :
        std::unique_ptr<T>(std::move(rhs))
    {
        // Print something for observation. Remember to remove it.
        std::cout << "opaque_pointer(std::unique_ptr<T>&& rhs)" << endl;
    }

    // The copy constructor you want!
    opaque_pointer(const opaque_pointer& rhs)
        :
        std::unique_ptr<T>(std::make_unique<T>(*rhs))
    {
        // Print something for observation. Remember to remove it.
        std::cout << "opaque_pointer(const opaque_pointer& rhs)" << endl;
    }

    // It needs a move constructor too.
    opaque_pointer(opaque_pointer&& rhs)
        :
        std::unique_ptr<T>(std::move(rhs))
    {
        // Print something for observation. Remember to remove it.
        std::cout << "opaque_pointer(opaque_pointer&& rhs)" << endl;
    }
};

然后,我们可以尝试一下。

struct Widget
{
    int i;
    Widget(int i) : i(i) {}
    ~Widget()
    {
        std::cout << "~Widget()" << " " << i << endl;
    }

    Widget& operator += (int rhs) { i += rhs; return *this; }

    friend std::ostream& operator<<(std::ostream& out, const Widget& w)
    {
        return out << w.i;
    }
};

int main()
{
    std::cout << "+++ Let's try the simple constructor and copy constructor! +++" << endl;

    opaque_pointer<Widget> op = make_unique<Widget>(100);
    opaque_pointer<Widget> op2 = op;

    *op2 += 2;

    cout << "Value: " << *op << " " << *op2 << endl;
    cout << "Owning: " << !!op << " " << !!op2 << endl;

    std::cout << endl << "+++ Let's move it! +++" << endl;

    opaque_pointer<Widget> op3 = std::move(op);

    *op3 += 30;

    cout << "Value: " << *op3 << endl;
    cout << "Owning: " << !!op << " " << !!op3 << endl;

    std::cout << endl << "+++ By the way, does it really manage life time? +++" << endl;
}

结果是这样的。

+++ Let's try the simple constructor and copy constructor! +++
opaque_pointer(std::unique_ptr<T>&& rhs)
opaque_pointer(const opaque_pointer& rhs)
Value: 100 102
Owning: 1 1

+++ Let's move it! +++
opaque_pointer(opaque_pointer&& rhs)
Value: 130
Owning: 0 1

+++ By the way, does it really manage life time? +++
~Widget() 130
~Widget() 102