我一直在阅读很多关于Singleton模式是好/坏/丑的讨论,以及应该用什么代替它。
通用实现需要Instance()
方法,如果尚未创建对象,则调用私有构造函数。
我的问题并不适合Singleton模式,但是可以通过覆盖new
来限制类的实例数吗?如果说我们只想要一个实例,那么返回已经创建的实例?
如果这是可能的,这甚至是一个好主意吗?
目标是在任何需要访问类的类中,只需声明一个私有成员,它将在第一次初始化,然后引用其余成员。
ClassA {
MyClass classRef;
}
ClassB {
MyClass classRef;
}
因此,如果MyClass
仅限于一个实例,则根据实例化的顺序,其中一个对象实际上会创建一个新的MyClass,而另一个将只获取它的引用。
答案 0 :(得分:2)
可以在堆栈上和其他对象中静态分配对象。如果你只想要一个实例,你需要以某种方式禁止所有这些。重载operator new
对此无效。使构造函数private
或protected
成为可能,但这也会为类的用户禁用operator new
。
此外,operator new
返回的不是对象,而是将在其中创建对象的块内存。如果返回已分配的块,则每次调用operator new
时都会在其上运行构造函数。
答案 1 :(得分:1)
这听起来像某种非并发worker pool。
当大量作业将由多个服务/驱动程序执行并且您希望实现限制,或者可能排队作业以防止交换文件抖动或某些其他资源约束时,这可能是一个好主意。
覆盖new
可能不是正确的方法。让任务场本身就是一个对象,并从那里“分配”任务。任务句柄包装器对象的原始分配应该没有这些考虑因素。
是的,单身人士很难看(或至少是一个好主意的丑陋实施)。
答案 2 :(得分:1)
覆盖new
无效。首先,它不会阻止额外的
堆栈上的实例或静态变量。其次,您定义的operator
new
仅分配内存;构造函数仍然会
被称为(如果单身人士有可能造成的灾难性影响)
可变状态)。
答案 3 :(得分:0)
通过将计数器保持为静态成员变量,可以更直接地限制实例化的数量:
template<unsigned int N>
class N_gleton {
private:
static int number_of_instances_;
public:
enum { MAX_NUMBER_OF_INSTANCES = N };
N_gleton() {
assert(number_of_instances_ < MAX_NUMBER_OF_INSTANCES);
++number_of_instances_;
}
};
template<unsigned int N>
int N_gleton<N>::number_of_instances_ = 0; // initial value