提供可配置的默认实例

时间:2016-05-16 12:21:46

标签: c++

在c ++中是否有规范模式/最佳实践方法来提供类的默认实例,其构造函数需要参数?它应该例如可以这样使用:

int main() {
    //At startup:
    //Parameterize default instance with some runtime Data
    Foo::initDefault(getConfigFromFile().getDefaultFooVal());

    //1) Use default instance somewhere else in the code:
    Foo::getDefault().doSomething();

    //2) 
    Foo::getDefault().doSomethingElse();

    //3) somewhere else in the code, maybe even before the call to initDefault()
    Foo myFoo(5);
    myFoo.doSomething();
}

void bar(const Foo& foo = Foo::getDefault()) {
    //... do something with foo
}

请注意

  1. 1)和2)对同一个实例进行操作
  2. 如3)所示,Foo不是单身人士
  3. 我想避免提供默认构造函数

2 个答案:

答案 0 :(得分:2)

我通常的做法是这样的:

struct Foo {
    Foo(int i){...};

    static Foo& initDefault(int i){
        static Foo foo(i);
        return foo;
    }

    static Foo& getDefault() {
         static Foo& foo = initDefault(-1);
         return foo;
    }  

    void doSomething(){...}
};

答案 1 :(得分:1)

如果你真的不想允许“默认”实例,我会使用指针来指示单例实例的存在:

struct Foo {
    Foo(int i){...};

    static Foo& initDefault (int i) {
        static Foo foo(i);
        if (pFoo) {
            throw "Foo's instance is already initialized.";
            // or: foo = Foo(i); if you want to allow re-initialization
        }
        else {
            pFoo = &foo;
        }
        return foo;
    }

    static Foo& getDefault() {
         if (!pFoo) {
             throw "Cannot get Foo's instance before initializing it.";
         }
         return *pFoo;
    }  

    void doSomething(){...}

private:
    static Foo *pFoo;
};

Foo* Foo::pFoo{nullptr};

通过上述内容,您可以通过一种简单的方法来测试实例是否已初始化,而无需动态分配单例实例。