C++ 防止对象在其工厂方法之外实例化
假设我有一个带有工厂方法的类C++ 防止对象在其工厂方法之外实例化,c++,oop,factory-pattern,C++,Oop,Factory Pattern,假设我有一个带有工厂方法的类 class A { public: static A* newA() { // Some code, logging, ... return new A(); } } 是否可以防止使用new实例化此类的对象,以便factory方法是创建对象实例的唯一方法 当然;只需将构造函数设置为私有(如果这是基类,则受保护): 如果需要,还应将复制构造函数设置为私有/受保护 和一如既往,您应该强烈考虑返回智能指针而不是原始指针,为了简化内存管理问题。
class A {
public:
static A* newA()
{
// Some code, logging, ...
return new A();
}
}
是否可以防止使用
new
实例化此类的对象,以便factory方法是创建对象实例的唯一方法 当然;只需将构造函数设置为私有(如果这是基类,则受保护):
如果需要,还应将复制构造函数设置为私有/受保护
和一如既往,您应该强烈考虑返回智能指针而不是原始指针,为了简化内存管理问题。
您可能还希望将复制构造函数设置为私有,或者使用新的C++11语法,您可以显式地告诉编译器不要复制它,并使用如下方式将默认构造函数设置为私有:struct NonCopyable {
NonCopyable & operator=(const NonCopyable&) = delete;
NonCopyable(const NonCopyable&) = delete;
NonCopyable() = default;
};
class A : NonCopyable {
public:
static std::shared_ptr<A> newA()
{
// Some code, logging, ...
return std::make_shared<A>();
}
private:
A() {} // Default constructor
};
class A {
public:
static A* newA()
{
// Some code, logging, ...
return new A();
}
private:
A() {} // no outsider default constructor
A(const A& rhs); // no copy
A& operator=(const A& rhs); // no assignment
};
int main()
{
A x; // C2248
A y(x); // C2248
x = y; // C2248
A* p = A::newA(); // OK
std::cin.get();
return 0;
}
这个答案只不过是对std::unique_ptr…Edit:Meh,不要去鬼魂编辑你的答案p谢谢你的回答。至于智能指针,我知道。我通常会用它们。但是,这个特定对象的内存管理有点复杂,出于性能原因,无法在任何地方使用
共享\u ptr
。我一直想知道,假设您的工厂返回一个唯一的\u ptr,但其中一个确实需要一个共享的\u ptr(反之亦然),如何做到这一点?@stijn:有一个从unique\u ptr
到shared\u ptr
的转换。如果你能归还前者,如果你必须归还后者。单身是邪恶的。请看这里:@Truth:这看起来不像一个单例。@OliCharlesworth:一个返回自身实例并阻止其他人实例化它的工厂?看起来很危险。这实际上不是一个单例(会有多个实例),但我明白了。我尽量避免使用这种模式。这种模式非常好,并且用于各种原因(与单身无关,这是邪恶的)。更好的方法是返回某种类型的智能指针(特别是当您需要从\u this启用\u shared\u时,或者当您操作垃圾收集句柄时)。好的一点是,实际上我会避免大部分这种情况,在大多数情况下可能只使用std::unique\u ptr
。需要一些调整
class A {
public:
static A* newA()
{
// Some code, logging, ...
return new A();
}
private:
A() {} // no outsider default constructor
A(const A& rhs); // no copy
A& operator=(const A& rhs); // no assignment
};
int main()
{
A x; // C2248
A y(x); // C2248
x = y; // C2248
A* p = A::newA(); // OK
std::cin.get();
return 0;
}