2016-07-28 136 views
3

我想在特定实例的构造函数中初始化静态成员变量。这是一个坏主意吗?在实例的构造函数中初始化静态成员

情况如下。我有一个静态成员变量,这个类的所有实例应该共享。通常,我只是使用静态初始化器。但是,在构造函数被调用之前,我没有构造静态对象所需的必要信息。但是当然,我不想在每次构造函数被调用时创建一个新对象,所以我想要做这样的事情。

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的migth是不同的调用的Foo构造不同。这对我来说并不重要。

这是不好的软件设计吗?我感觉有点奇怪,在构造函数中初始化一个静态对象。但这与单件设计模式没有什么不同。所以也许它没关系?

编辑

感谢您的意见家伙。人们似乎并不喜欢这种设计。我将对其进行修改,以便在Foo的第一个实例化之前创建一个Bar,并在Foo的构造函数中将Bar *作为参数传递。每个Foo将有一个指向Bar的指针,我将确保所有Foo都指向相同的Bar。那个更好吗?

+1

请注意,你不会做初始化。你将会做任务。 – NathanOliver

+0

如何获得应该用于_initialization_的值?它仅在运行时才可用吗?顺便说一句,你的样本不会编译。 –

+3

单线看起来没问题。多线程竞争条件。 –

回答

1

这是不好的软件设计吗?

一般情况下,它会被认为是的,是的。有很多原因为什么Singleton Pattern或以这种方式具有静态变量被认为是不好的设计。


但它不是从Singleton设计模式的不同。所以也许它没关系?

如果你真的想使之成为Singleton模式你应该宁愿使用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应该弥补它自己的一个辛格尔顿那么,你用它在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; 
}; 
+0

*“但是,我没有必要的信息来构造静态对象,直到构造函数被调用”* ... – Jarod42

+1

@ Jarod42这是一个指标,设计是有缺陷的,'酒吧'不应该在一个与'Foo'的静态关系。我只是想澄清一下_real_ Singleton Pattern的区别。 –

相关问题