提供可配置的默认实例 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 } 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(){...} };
注意提供可配置的默认实例 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 } 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(){...} };,c++,C++,注意 1) 2)对同一实例进行操作 如图3所示,Foo不是一个单例 我希望避免提供默认构造函数 我通常的做法如下: int main() { //At startup: //Parameterize default instance with some runtime Data Foo::initDefault(getConfigFromFile().getDefaultFooVal()); //1) Use default instance somewhere
Foo
不是一个单例我通常的做法如下:
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
}
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(){...}
};
我通常的做法如下:
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
}
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(){...}
};
如果您确实不想允许使用“默认”实例,我将使用一个指针来指示是否存在singleton实例:
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};
通过以上内容,您可以使用一种简单的方法来测试实例是否已初始化,而无需动态分配您的单例实例。如果您确实不想允许使用“默认”实例,我将使用指针指示单例实例的存在:
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};
有了以上内容,您就有了一种简单的方法来测试实例是否已初始化,而无需动态分配您的单例实例。此实例是否会在整个程序中共享?这是一种单音,扩展为提供另一个实例吗?@HumamHelfawi:是的,这个实例会在整个程序中共享吗?它是一种单音,扩展为提供另一个实例吗?@HumamHelfawi:非常是的,如果您不想允许创建
initDefault(-1)
(这就像您显然不想要的默认构造函数),您可以有一个私有静态属性,例如pFoo
初始化为nullptr
(static Foo*pFoo=nullptr;
)然后在initDefault
中将pFoo
设置为&Foo
,以便在getDefault
中测试pFoo
是否为nullptr
并相应地抛出异常。如果您不想允许创建initDefault(-1)
(这类似于您显然不想要的默认构造函数),您可以有一个私有静态属性,例如,pFoo
初始化为nullptr
(static Foo*pFoo=nullptr;
)然后在initDefault
中将pFoo
设置为&foo
,这样您就可以在getDefault
中测试pFoo
是否为nullptr
,并相应地抛出异常。