我想在特定实例的构造函数中初始化一个静态成员变量。这是个坏主意吗?
情况如下。我有一个静态成员变量,该类的所有实例都应该共享。通常,我只使用静态初始化程序。但是,在构造函数被调用之前,我没有构造静态对象所需的必要信息。但是当然,我不想每次调用构造函数时都创建一个新对象,所以我想做这样的事情。
class Foo
{
static Bar * bar;
Foo( Xyz xyz);
};
Bar * Foo::bar = nullptr;
Foo::Foo(Xyz xyz)
{
if (Foo::bar == nullptr)
{
// initialize static bar
Foo::bar = new Bar(xyz);
}
}
我当然知道xyz
对于Foo
的构造函数的不同调用,migth会有所不同。这对我来说无关紧要。
这是不好的软件设计?我觉得在构造函数中初始化一个静态对象有点奇怪。但它与单身设计模式没有什么不同。也许这样可以吗?
修改
感谢评论家伙。似乎人们不是这种设计的粉丝。我将对其进行修改,以便在Bar
的第一个实例化之前创建一次Foo
,并在Bar *
的构造函数中传递Foo
作为参数。每个Foo
都会指向Bar
,我会确保所有Foo
都指向同一个Bar
。那更好吗?
答案 0 :(得分:1)
这是不好的软件设计吗?
一般来说,它会被认为是,是的。 Singleton Pattern 或以这种方式使用静态变量被认为是错误设计的原因有很多。
但它与单身设计模式没有什么不同。也许这样可以吗?
如果你真的想要制作 Singleton Pattern ,你应该使用Scott Meyer's technique:
class Foo
{
static Bar* bar(Xyz xyz) {
static Bar barInstance(xyz);
return &barInstance;
}
Foo( Xyz xyz) : xyz_(xyz) {}
void baz() {
Bar* b = bar(xyz_);
// use b ...
}
private:
Xyz xyz_;
};
此代码将是线程安全的,并且无需检查nullptr
。
虽然Bar
应该构成一个 Singleton ,但是你需要在Foo
中使用它:
class Bar {
public:
static Bar& getInstance(Xyz xyz) {
static Bar barInstance(xyz);
return &barInstance;
}
private:
Bar(Xyz xyz) : xyz_(Xyz) {}
Bar(const Bar&) delete;
Bar(Bar&&) delete;
Bar& operator=(const Bar&) delete;
Bar& operator=(Bar&) delete;
Xyz xyz_;
};
class Foo {
public:
Foo(Xyz xyz) barRef(Bar::getInstance(xyz)) {
// ^^^ Notice 1st instance of Foo created
// wins to create the Bar actually
}
private:
Bar& barRef;
};