使用new关键字限制实例数

时间:2011-07-12 14:58:48

标签: c++ singleton override new-operator

我一直在阅读很多关于Singleton模式是好/坏/丑的讨论,以及应该用什么代替它。

通用实现需要Instance()方法,如果尚未创建对象,则调用私有构造函数。

我的问题并不适合Singleton模式,但是可以通过覆盖new来限制类的实例数吗?如果说我们只想要一个实例,那么返回已经创建的实例?

如果这是可能的,这甚至是一个好主意吗?

目标是在任何需要访问类的类中,只需声明一个私有成员,它将在第一次初始化,然后引用其余成员。

ClassA {
    MyClass classRef;
}

ClassB {
    MyClass classRef;
}

因此,如果MyClass仅限于一个实例,则根据实例化的顺序,其中一个对象实际上会创建一个新的MyClass,而另一个将只获取它的引用。

4 个答案:

答案 0 :(得分:2)

可以在堆栈上和其他对象中静态分配对象。如果你只想要一个实例,你需要以某种方式禁止所有这些。重载operator new对此无效。使构造函数privateprotected成为可能,但这也会为类的用户禁用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