класс Singleton с конструктором не по умолчанию - PullRequest
0 голосов
/ 04 октября 2018

У меня есть class, который должен стать синглтоном.Все хорошо, что у него есть конструктор не по умолчанию, то есть он принимает три аргумента.Лучшее, что я могу придумать, это установить конструктор private, а затем предоставить какую-то public функцию «настройки».Есть ли лучшие решения?Моя работа до сих пор выглядит примерно так - любые идеи по улучшению этого приветствуются!

Ответы [ 3 ]

0 голосов
/ 04 октября 2018

Адаптация Ответ Стива для предоставления функции настройки для синглтон-класса:

class Foo {
 public:
  static Foo& GetInstance() { return SetupInstance(-1, -1); }

  static Foo& SetupInstance(int a, int b) {
    static Foo foo(a, b);
    return foo;
  }

 private:
  Foo(int a, int b) {
    // ...
  }
};

Поскольку конструктор static синглтона get вызывается только один раз, несколько вызовов SetupInstance не будет заново создавать новый объект Foo, но всегда будет возвращать объект, который был создан при первом вызове.

0 голосов
/ 04 октября 2018

Не используйте реальный синглтон (который обрабатывает создание + уникальный экземпляр + глобальный доступ) и адаптируйте его:

class MyClass
{
private:
    int data = 0;
    int _AA;
    int _BB;
    int _CC;

    static std::unique_ptr<MyClass> uniqueInstance;

    MyClass(int AA, int BB, int CC) : _AA(AA), _BB(BB), _CC(CC) {}

    MyClass(const MyClass&) = delete;
    MyClass& operator =(const MyClass&) = delete;

public:

    static void Create(int AA, int BB, int CC)
    {
        // if (uniqueInstance) throw std::runtime_error("Call it only once");
        uniqueInstance = std::make_unique<MyClass>(AA, BB, CC);
    }

    static MyClass& GetInstance()
    {
         if (!uniqueInstance) throw std::runtime_error("Call Create before");
         return *uniqueInstance;
    }

    int getData() const { return this->data; }
    void setData(int data) { this->data = data; }
    int getAA() const { return _AA; }
};

std::unique_ptr<MyClass> MyClass::uniqueInstance;

int main(){
    MyClass::Create(111, 222, 333);
    auto& a = MyClass::GetInstance();
    std::cout << "dat " << a.getData() << " _AA " << a.getAA() << std::endl;
    a.setData(100);
    std::cout << "dat " << a.getData() << " _AA " << a.getAA() << std::endl;  
}
0 голосов
/ 04 октября 2018

Вы можете использовать статическую функцию фабрики / получения, которая вызывает приватный конструктор.Примерно так:

class Foo {
public:
    static Foo& GetInstance() {
        static Foo foo(param1, param2);
        return foo;
    }
private:
    Foo(int a, int b) {
        // ...
    }
}

Конечно, это требует, чтобы ваша заводская функция каким-то образом знала параметры.

...