Ограничьте количество экземпляров с новым ключевым словом - PullRequest
2 голосов
/ 12 июля 2011

Я читал много споров о том, является ли шаблон Singleton хорошим / плохим / уродливым, и что следует использовать вместо него.

Обычная реализация требует метода Instance(), который вызываетзакрытый конструктор, если объект еще не создан.

Мой вопрос не совсем соответствует шаблону Singleton, но можно ли ограничить количество экземпляров класса, переопределив new?И если, скажем, нам нужен только один экземпляр, вернуть уже созданный экземпляр?

Если это возможно, это даже хорошая идея?

Цель состоит в том, чтобы в любом классе, нуждающемся в доступе ккласс, можно было бы просто объявить закрытый член, который будет инициализирован в первый раз, а затем будет использоваться для остальных.

ClassA {
    MyClass classRef;
}

ClassB {
    MyClass classRef;
}

Так что если MyClass ограничен одним экземпляром, в зависимости от порядкаНапример, один из этих объектов фактически создаст новый MyClass, а другой просто получит его ссылку.

Ответы [ 4 ]

2 голосов
/ 12 июля 2011

Объекты могут быть размещены статически, в стеке и внутри других объектов.Если вы хотите только один экземпляр, вам нужно как-то запретить все это.Перегрузка operator new не поможет вам в этом.Сделайте конструкторы private или protected, но это отключит operator new и для пользователей класса.

Более того, то, что возвращает operator new, является не объектом, а памятью блокав котором объект будет создан.Если вы возвращаете уже выделенный блок, конструктор будет запускаться над ним каждый раз, когда вызывается operator new.

1 голос
/ 12 июля 2011

Переопределение new не будет работать.Во-первых, это не предотвратит дополнительные экземпляры в стеке или в качестве статических переменных.Во-вторых, operator new, который вы определяете, только выделяет память;конструктор будет по-прежнему вызываться (что может привести к катастрофическим последствиям, если синглтон имеет изменяемое состояние).

1 голос
/ 12 июля 2011

Это звучит как непараллельный рабочий пул * некоторого рода 1002 *.

Это может быть хорошей идеей, когда большое количество заданий будет выполняться несколькими службами./ driver, и вы хотите реализовать задания регулирования, или, возможно, задания очереди, чтобы предотвратить смещение файла подкачки, или некоторые другие ограничения ресурсов.

Переопределение new, вероятно, не является правильным способом сделать это.Пусть ферма задач должна быть самим объектом и «распределять» задачи оттуда.Необработанное выделение объекта-обертки дескриптора задачи должно быть свободным от таких соображений.

И да, синглтоны - это некрасиво (или, по крайней мере, уродливая реализация хорошей идеи).

0 голосов
/ 12 июля 2011

Вы можете намного проще ограничить количество экземпляров, сохранив счетчик в качестве статической переменной-члена:

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
...