首页 > 解决方案 > 如何使用 unique_ptr 实现零规则

问题描述

我实际上想在一个类上用一个 unique_ptr 做一个零规则的例子。这是我的示例代码:

#include <iostream>
#include <memory>

// Rule of zero?
template <class T>
class myStruct
{
    int m_timesToPrint{0};
    std::unique_ptr<T> m_ptr;

public:
    myStruct(int tToPrint, const T& val)
    : m_timesToPrint(tToPrint), m_ptr(std::make_unique<T>(val))
    { }

    myStruct() = default;
    myStruct(const myStruct&) = default;

    friend std::ostream& operator<<(std::ostream& os, const myStruct<T>& rhs)
    {
        for(auto i = 0; i < rhs.m_timesToPrint; ++i)
        {
            os << *(rhs.m_ptr.get()) << "\n";
        }
        os << "---------------\n";
        return os;
    }
};



int main()
{
    myStruct<int> m1(3, 3);
    // myStruct<int> m2 = m1; // Error!

    std::cout << m1;
    // std::cout << m2;

    return 0;
}

显然,我在 m2 = m1 行上有问题,因为unique_ptr(const unique_ptr&) = deleted被删除了,但是我该怎么做那个例子呢?

谢谢!

标签: c++pointersuniqueruleszero

解决方案


使用零规则,甚至不需要默认构造函数:

template <class T>
class myStruct
{
    int m_timesToPrint{0};
    std::unique_ptr<T> m_ptr;

public:
    myStruct(int tToPrint, const T& val)
    : m_timesToPrint(tToPrint), m_ptr(std::make_unique<T>(val))
    { }

    myStruct() = default;
    // myStruct(const myStruct&) = default; // not needed

    // ... other stuff
};

显然,我在m2 = m1网上遇到了问题,因为unique_ptr(const unique_ptr&) = deleted被删除了,但是我该怎么做那个例子呢?

好吧,您的零规则已正确实施。如果您想让副本正常工作,您需要一个不同于std::unique_ptr.

我的建议是创建一个复制其资源的指针类型,或者std::shared_ptr如果您想共享资源而不是复制它,则使用它。

这样的指针可能如下所示:

template<typename T>
struct clone_ptr {
    clone_ptr(clone_ptr const& other) : /* initialize `_ptr` with copy */ {}

    clone_ptr(clone_ptr&&) = default;
    clone_ptr& operator=(clone_ptr&&) = default;

    // implement copy assign

    // implement operators

private:
    std::unique_ptr<T> _ptr;
};

推荐阅读