初始化实例的构造函数内的静态成员
Initialize static member inside constructor of an instance
我想在特定实例的构造函数中初始化一个静态成员变量。这是个坏主意吗?
情况如下。我有一个静态成员变量,这个类的所有实例都应该共享。通常,我只会使用一个静态初始值设定项。但是,在调用构造函数之前,我没有构造静态对象所需的必要信息。当然,我不想每次调用构造函数时都创建一个新对象,所以我想做这样的事情。
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);
}
}
当然,我知道对于Foo
的构造函数的不同调用,xyz
可能会有所不同。这对我来说并不重要。
这是糟糕的软件设计吗?在构造函数中初始化一个静态对象时,我觉得有点奇怪。但它与单例设计模式没有太大区别。所以也许没关系?
编辑
谢谢你们的评论。人们似乎不喜欢这种设计。我将对其进行修改,以便在Foo
的第一个实例化之前创建一次Bar
,并在Foo
的构造函数中传递一个Bar *
作为参数。每个Foo
都有一个指向Bar
的指针,我将确保所有Foo
都指向同一个Bar
。这样更好吗?
这是糟糕的软件设计吗?
一般来说,是的。Singleton模式或以这种方式具有静态变量被认为是糟糕的设计,原因有很多。
但它与单例设计模式没有太大区别。所以也许没关系?
如果你真的想让它成为Singleton模式,你应该使用Scott Meyer的技术:
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;
};
相关文章:
- 为什么 std::sort 找不到合适的(静态成员)函数重载?
- 指向重载静态成员的函数指针 - 在unique_ptr中用作自定义删除器
- 在成员构造函数之后调用基类构造函数
- 函数指针静态,构造函数
- C++:如何在对象构造过程中调用初始值设定项列表之外的成员构造函数
- 用作成员构造函数参数的函数的求值顺序
- 从成员构造函数(Brace Initializer vs Initializer列表)抛出异常
- 不正确的成员构造函数定义
- 返回本地静态的函数和返回静态成员的函数之间有什么区别(对象大小、性能等)?
- 指向结构中作为静态成员的函数的指针
- 我可以基于模板参数将某个值传递给成员构造函数吗
- boost::p ython 纯虚拟基类,具有静态工厂构造函数和 std::unique_ptr
- cpp-静态成员和函数
- 在最终类中调用静态方法的静态基构造函数的设计模式
- 控制静态对象构造函数的顺序
- 在类定义中调用成员构造函数
- 使用已删除的副本构造函数和初始值设定项列表重载调用类定义中的成员构造函数
- 正在从成员构造函数调用虚拟函数
- 来自静态变量构造函数/析构函数的异常
- 需要从静态成员调用函数(由静态指针引用)