使用受保护构造函数和复制构造函数创建 C++ 非堆工厂对象
Posted
技术标签:
【中文标题】使用受保护构造函数和复制构造函数创建 C++ 非堆工厂对象【英文标题】:C++ non heap Factory object creation with protected constructor and copy constructor 【发布时间】:2016-12-09 12:07:55 【问题描述】:由于 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();
但看起来不太对劲。
还有什么其他方法可以解决这个问题?
【问题讨论】:
【参考方案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
【讨论】:
最后我选择了 unique_ptr。当 dtor 参与每一个移动操作时,会出现很多问题。 @user1079475 你比我更了解用例。但我以为你想要堆栈上的对象? 是的,我做到了,但是将对象从方法范围移动到调用范围时太麻烦了。这些对象具有互斥体属性,并且需要在堆上移动这些互斥体等等。麻烦多多收效甚微以上是关于使用受保护构造函数和复制构造函数创建 C++ 非堆工厂对象的主要内容,如果未能解决你的问题,请参考以下文章
C++:为啥我的 DerivedClass 的构造函数无法访问 BaseClass 的受保护字段?