2009-03-01 128 views
1

可以在基类中定义一个静态成员变量,并且有多个派生类,每个派生类都使用它自己的此成员变量的实例?子类的静态成员变量

下面的代码编译成功,并打印正确的输出,但我仍然不确定做这样的事情是一种好的做法。 在下面的例子中,如果我明确定义了s的一个实例(通过调用:string A :: s;),但它实际上如何工作,但实际上使用了2个实例?

class A 
{ 
    protected: 
    void SetS(string new_s){s = new_s;} 
    void PrintS(){cout << s << endl;}; 
    private: 
    static string s; 

}; 

class B : public A 
{ 
    public: 
    void foo(){ SetS("bbb"); PrintS();}; 
}; 

class C : public A 
{ 
    public: 
    void foo(){ SetS("ccc"); PrintS();}; 
}; 

string A::s; 

int main() 
{ 
    B b; 
    b.foo(); // results in output: bbb 
    C c; 
    c.foo(); // results in output: ccc 
    b.foo(); // results in output: bbb 
} 

回答

7

的确很遗憾地使用继承。根据良好的面向对象设计原则,基类应该理想地定义接口并且尽可能地包含尽可能少或者没有状态。

这是可行的,因为您的foo()每次调用时都会重置值A::s。尝试打印地址A::s。只有一个对象。如果您没有每次都设置该值,并且您有多个对象使用另一个成员函数bar()来读取A :: s的值,则这将不起作用。

如果BC对象也在单独的线程中创建,则可能会遇到同步问题。你会以UB结束。

+0

优秀的答案。 +1。 – 2009-03-01 11:22:41