C 非堆工厂对象创建具有受保护的构造函数和复制构造函数



由于具有raii功能,我希望我的对象只能放置在堆栈上,而且作为对象创建的功能也应委派给我不希望ocpy构造函数可用于使用的专业工厂。p>所以我做了这样的事情。

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();
}

,但看起来不正确。

其他方法可以处理?

我这样做的方式将是删除副本,启用移动并允许通过任何可以创建施工密钥的类施工。

// 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
}

最新更新