Singleton-класс и Абстрактный базовый класс в C++

Если вы хотите вставить большой кодовый блок с необязательными номерами строк и т. Д., Используйте макрос макросов (доступно в разделе Макросы -> Другое).

11
задан MSalters 7 July 2009 в 09:53
поделиться

7 ответов

Вы всегда можете сделать что-то вроде этого:

class IFoo {};
class Foo : public IFoo {};

template <typename T>
class Singleton
{
    // ..
};

typedef Singleton<Foo> FooSingleton;

int main()
{
    FooSingleton::Instance()->foo();

    return 0;
}
2
ответ дан 3 December 2019 в 04:33
поделиться

Раздражающий мета-ответ: «Почему вы используете синглтон?» Мне еще предстоит найти ситуацию, когда вам действительно нужно его использовать. ИМХО, его недостатки перевешивают его достоинства, в реальных жизненных ситуациях.

Возможно, вам понадобится что-то вроде 'boost :: noncopyable'.

См. Этот пост для получения дополнительной информации

2
ответ дан 3 December 2019 в 04:33
поделиться

Вы не можете этого сделать. IFoo - это интерфейс по дизайну и определению. Таким образом, количество экземпляров равно 0. С другой стороны, определение одноэлементного класса состоит в том, что у вас есть 1 экземпляр. 0! = 1.

8
ответ дан 3 December 2019 в 04:33
поделиться

Я думаю, что лучшим решением было бы ввести здесь фабричный класс или метод. Только представьте себе следующее:

struct FooCreator
{
  typedef IFoo*     result_type;

  result_type operator()()const
  {
     return new Foo;
  }
};

template<class Factory>
struct Singleton
{

  static typename Factory::result_type instance()
  {
    if(instance_==typename Factory::result_type())
      instance_ = Factory()();
    return instance_;
  } 

private:
  Singleton(){};

  static typename Factory::result_type instance_;
};

template<class F>
typename F::result_type Singleton<F>::instance_ = typename F::result_type();

С уважением,
Ованес

0
ответ дан 3 December 2019 в 04:33
поделиться

Мне пришлось сделать что-то подобное, чтобы добавить модульные тесты в некоторый устаревший код. Мне пришлось заменить существующий синглтон, в котором использовался шаблон. Я дал два параметра одноэлементному шаблону, первый - это интерфейс, а второй - реализация.

Однако мне также пришлось добавить метод setTestInstance , чтобы позволить модульным тестам переопределить экземпляр во время выполнения.

template <typename IfaceT, typename ImplT>
class Singleton
{
public:
   static IfaceT* Instance() {
      if (m_instance == NULL) {
         m_instance = new ImplT();
      }
      return m_instance;
   }

   // Only used for unit tests 
   // Takes ownership of instance
   static void setTestInstance(IfaceT* instace) {
      m_instance = instance;
   }
private:
   static IfaceT * m_instance;
};

В этом случае setTestInstance должен использовать std: : auto_ptr и m_instance должны быть boost :: scoped_ptr . Чтобы избежать утечки памяти.

0
ответ дан 3 December 2019 в 04:33
поделиться

Взгляните на это так: в вашей программе нет ничего, что могло бы сообщить компилятору, какую реализацию интерфейса IFoo он должен создавать. Помните, что помимо Foo могут быть и другие реализации.

Если вы хотите использовать класс через интерфейс и определить, какая фактическая реализация должна использоваться где-то еще, взгляните на шаблон Abstract Factory .

0
ответ дан 3 December 2019 в 04:33
поделиться

Вы бы хотели использовать что-то вроде

IFoo my_foo = Singleton<Foo>::Instance();
my_foo->foo();

В основном вам нужно будет создать экземпляр шаблона Singleton, используя конкретный класс (в данном случае ваш класс Foo), и, учитывая, что ваш Foo является производным от IFoo, вы можете ссылаться на него через базовый указатель. Вы не можете напрямую создать экземпляр шаблона, используя неполный или абстрактный класс.

10
ответ дан 3 December 2019 в 04:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: