假设我需要在构造函数初始化任何成员变量之前调用一个空闲的GlobalInitializer()。例如:
class Foo {
public:
Foo() : bar_()
{
// calling GlobalInitializer() here is too late
}
Bar bar_;
};
在Foo中调用GlobalInitializer()为时已晚,因为我需要在bar_初始化之前调用它。我的hacky解决方法是创建一个超级班:
class MyInitializer {
protected:
MyInitializer() {
GlobalInitializer();
}
};
class UglyFoo : public MyInitializer
{
public:
UglyFoo() : bar_()
{ }
Bar bar_;
};
UglyFoo完成了工作,但它需要这个丑陋的MyInitializer类。是否有更清洁的设计模式或重构可以达到相同的效果?
附加说明:GlobalInitializer()是一项昂贵的调用,除非用户实例化Foo(),否则我要避免这种调用。 GlobalInitializer()内部有针对多个调用的警卫。此外,可能还有其他类,比如说FooBar,也需要调用GlobalInitializer(),但在一个进程中,GlobalInitializer()实际上会工作一次(如果实例化Foo或FooBar)或者甚至不执行一次(如果没有) Foo或FooBar的实例化。
答案 0 :(得分:4)
class Foo {
private:
struct Initializer {
Initializer() { GlobalInitializer(); }
};
Initializer initializer__; // declare before bar__ to ensure it is constructed first
public:
Foo() : bar_()
{
}
Bar bar_;
};
答案 1 :(得分:1)
你应该重新思考你的设计。
好的设计意味着loose-coupling。如果您的对象创建依赖于不同的方法调用,那么就会出现严重错误。
如果你确实需要这个,你应该在GlobalInitializer
的构造函数中调用bar_
,但最好的方法是重新考虑你的设计。
答案 2 :(得分:0)
你所做的事情似乎违反了面向对象的价值观,因为你的课程不合理地依赖于他们之外的东西;我建议你重新设计你的课程以避免这种情况。
话虽这么说,一个适合你的设计模型但不让每个类继承另一个类的选项是将MyInitializer类创建为单例对象,并为依赖于这个初始化的每个类添加一个MyInitializer。单例只会在第一次实例化时执行初始化。
答案 3 :(得分:0)
据推测,你可以重构任何GlobalInitializer
初始化不再是全局的。然后,您可以选择如何为您的班级提供数据。你知道,因为globals are bad和所有。
答案 4 :(得分:0)
在梦中找到我:将bar_改为指针:
class Foo {
public:
Foo()
{
GlobalInitializer();
// now we can call GlobalInitializer() in time
bar_ = new Bar;
}
~Foo()
{
delete bar_;
}
private:
Bar* bar_;
};