статическая переменная-член подкласса - PullRequest
1 голос
/ 01 марта 2009

Можно ли иметь статическую переменную-член, определенную в базовом классе, и иметь несколько производных классов, каждый из которых использует свой собственный экземпляр этой переменной-члена?

Следующий код успешно компилируется и выводит правильный вывод, но я все еще не уверен, что делать что-то подобное - хорошая практика. В следующем примере, как это может работать, если я явно определяю только один экземпляр 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
}

1 Ответ

7 голосов
/ 01 марта 2009

Очень странное использование наследования. Базовый класс должен идеально определять интерфейсы и содержать как можно меньше или вообще не иметь состояния, если это возможно, в соответствии с хорошим принципом проектирования ОО.

Это работает, потому что ваш foo() сбрасывает значение A::s каждый раз, когда он вызывается. Попробуйте напечатать адрес A::s. Есть один и только один объект. Это не будет работать, если вы не устанавливаете значение каждый раз, и у вас есть несколько объектов, использующих другую функцию-член bar() для чтения значения A :: s.

Вы можете столкнуться с проблемами синхронизации, если объекты B и C также созданы в отдельных потоках. Вы получите UB.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...