是否可以在基类中定义静态成员变量,并且有几个派生类,每个派生类都使用自己的成员变量实例?
以下代码编译成功,并打印出正确的输出,但我仍然不确定做这样的事情是一个好习惯。 在下面的示例中,如果我只显式定义一个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
}
答案 0 :(得分:7)
确实非常奇怪地使用了继承。根据良好的OO设计原则,基类应该理想地定义接口,并且如果可能的话根本包含很少或根本不包含状态。
这是有效的,因为foo()
每次调用时都会重置A::s
的值。尝试打印A::s
的地址。只有一个对象。如果您不是每次都设置该值,并且您有多个对象使用另一个成员函数bar()
来读取A :: s的值,那么这将不起作用。
如果在单独的线程中创建B
和C
对象,则可能会遇到同步问题。你最终会得到UB。