使用new关键字限制实例的数量

Limit the number of instances with the new keyword

本文关键字:实例 new 关键字 使用      更新时间:2023-10-16

我读了很多关于Singleton模式好/坏/丑的争论,以及应该用什么来代替它。

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

我的问题真的不适合单例模式,但是有可能通过重写new来限制类的实例数量吗?如果我们只想要一个实例,返回已经创建的实例?

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

目的是在任何需要访问类的类中,只需声明一个private成员,第一次初始化该成员,然后在其余部分引用该成员。

ClassA {
    MyClass classRef;
}
ClassB {
    MyClass classRef;
}

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

对象可以静态分配,也可以在堆栈上分配,也可以在其他对象中分配。如果只需要一个实例,则需要以某种方式禁止所有这些实例。重载operator new不会帮助您解决这个问题。将构造函数设置为privateprotected可以,但这也会使该类用户禁用operator new

此外,operator new返回的不是一个对象,而是一个将在其中创建该对象的块内存。如果您返回一个已经分配的块,每次调用operator new时都将在它上面运行一个构造函数。

这听起来像是某种非并发工作池。

当大量作业将由多个服务/驱动程序执行时,这可能是一个好主意,并且您希望实现节流,或者可能队列作业以防止交换文件抖动,或其他一些资源约束。

重写new可能不是正确的方法。让任务场本身成为一个对象,并从那里"分配"任务。任务句柄包装器对象的原始分配不应该有这样的考虑。

是的,单例是丑陋的(或者至少是一个好想法的丑陋实现)

覆盖new无效。首先,它不会阻止额外的堆栈上的实例或作为静态变量。其次,您定义的operator new只分配内存;构造函数仍然会被调用(如果单例对象被调用,则可能产生灾难性的影响)可变状态)。

通过将计数器保持为静态成员变量,可以更直接地限制实例化的数量:

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