1

由于 RAII 功能,我希望我的对象只能放置在堆栈上,并且由于对象创建应该委托给专门的工厂,我不希望 ocpy 构造函数可以访问以供使用。

所以我做了这样的事情。

template<typename Product, Args ... >
class Creator : public Product
{
    public:
        static Product create(Args ... args)
        {
            return Product(args ... );
        }
};

class ProtectedClass
{
        ProtectedClass(const ProtectedClass& aThat)=delete;
        ProtectedClass& operator=(const ProtectedClass& aThat)=delete;
    protected:
        ProtectedClass(){}
};

class Spawner
{
    public:
        ProtectedClass getProtectedClass()
        {
            return Creator<ProtectedClass>::create();
        }
}

int main()
{
    Spawner spawner;
    //I need protectedClass to be enclosed within this frame
    ProtectedClass protectedClass = spawner.getProtectedClass(); // err copy constructor is delted
}

我可以做这样的事情

template<typename Product, Args ... >
class Creator : public Product
{
    public:
        Creator(Args ... args) : product_(args ...){}
        Product& get() const
        {
            return product_;
        }
    private:
        Product product_;
};

class Spawner
{
    public:
        std::unique_ptr<Creator<ProtectedClass>> getProtectedClassCreator()
        {
            return new Creator<ProtectedClass>();
        }
}

int main()
{
    Spawner spawner;
    std::unique_ptr<Creator<ProtectedClass>> creator = std::move(spawner.getProtectedClassCreator());
    ProtectedClass& protectedClass = creator->get();
}

但它看起来并不正确。

还有什么其他方法可以解决这个问题?

4

1 回答 1

1

我这样做的方法是删除副本,启用移动并允许通过任何可以创建构造键的类进行构造。

// forward declare any factories
class Spawner;

struct ProtectedClass
{
    class PermissionKey {
        // this is a private constructor
        PermissionKey() {};

        // make friends of the factories
        friend Spawner;
    };

    // all this is now public.
    // because we have declared a constructor, the default constructor
    // is deleted.    
    ProtectedClass(PermissionKey) {}

    // disable copies
    ProtectedClass(const ProtectedClass& aThat)=delete;
    ProtectedClass& operator=(const ProtectedClass& aThat)=delete;

    // enable moves so the factory can return it
    ProtectedClass(ProtectedClass&& aThat)=default;
    ProtectedClass& operator=(ProtectedClass&& aThat)=default;
};

class Spawner
{
public:
    ProtectedClass getProtectedClass()
    {
        // construct our spawned object - we can create keys
        return ProtectedClass(ProtectedClass::PermissionKey());
    }
};

int main()
{
    Spawner spawner;
    //I need protectedClass to be enclosed within this frame
    auto protectedClass = spawner.getProtectedClass(); // ok now
}
于 2016-12-09T12:58:47.447 回答