Унаследованы статические поля?

Когда статические члены наследуются, являются ли они статическими для всей иерархии или только для этого класса, то есть:

class SomeClass
{
public:
    SomeClass(){total++;}
    static int total;
};

class SomeDerivedClass: public SomeClass
{
public:
    SomeDerivedClass(){total++;}
};

int main()
{
    SomeClass A;
    SomeClass B;
    SomeDerivedClass C;
    return 0;
}

будет равно 3 во всех трех случаях, или это будет 2 для SomeClass и 1 для SomeDerivedClass?

Ответ 1

3 во всех случаях, поскольку static int total, унаследованный SomeDerivedClass, точно совпадает с SomeClass, а не отдельной переменной.

Изменить: фактически 4 во всех случаях, как @ejames заметили и указали в его ответе, которые видят.

Изменить: код во втором вопросе отсутствует в int в обоих случаях, но добавление его делает его ОК, то есть:

class A
{
public:
    static int MaxHP;
};
int A::MaxHP = 23;

class Cat: A
{
public:
    static const int MaxHP = 100;
};

работает отлично и с разными значениями для A:: MaxHP и Cat:: MaxHP - в этом случае подкласс "не наследует" статику от базового класса, так как, так сказать, он "скрывает" его с помощью его собственный одноименный.

Ответ 2

Ответ на самом деле четыре во всех случаях, так как построение SomeDerivedClass приведет к тому, что сумма будет увеличена дважды.

Вот полная программа (которую я использовал для проверки моего ответа):

#include <iostream>
#include <string>

using namespace std;

class SomeClass
{
    public:
        SomeClass() {total++;}
        static int total;
        void Print(string n) { cout << n << ".total = " << total << endl; }
};

int SomeClass::total = 0;

class SomeDerivedClass: public SomeClass
{
    public:
        SomeDerivedClass() {total++;}
};

int main(int argc, char ** argv)
{
    SomeClass A;
    SomeClass B;
    SomeDerivedClass C;

    A.Print("A");
    B.Print("B");
    C.Print("C");

    return 0;
}

И результаты:

A.total = 4
B.total = 4
C.total = 4

Ответ 3

Это 4, потому что когда производный объект создается, конструктор производного класса вызывает конструктор базового класса.
Таким образом, значение статической переменной увеличивается в два раза.

Ответ 4

#include<iostream>
using namespace std;

class A
{
public:
    A(){total++; cout << "A() total = "<< total << endl;}
    static int total;
};

int A::total = 0;

class B: public A
{
public:
    B(){total++; cout << "B() total = " << total << endl;}
};

int main()
{
    A a1;
    A a2;
    B b1;

    return 0;
}

Это будет:

A() total = 1
A() total = 2
A() total = 3
B() total = 4

Ответ 5

3 во всех трех случаях.

И для вашего другого вопроса, похоже, вам просто нужна переменная const вместо статики. Для провайдера может быть более понятным виртуальную функцию, которая возвращает требуемую переменную, которая переопределяется в производных классах.

Если этот код не вызывается на критическом пути, где требуется производительность, всегда выбирайте более интуитивно понятный код.

Ответ 6

Да, производный класс будет содержать одну и ту же статическую переменную, т.е. все они будут содержать 3 для общего числа (если предположить, что сумма была инициализирована где-то 0).

Ответ 7

Конструктор SomeClass() вызывается автоматически при вызове SomeDerivedClass(), это правило С++. Поэтому общая сумма увеличивается один раз за каждый объект SomeClass, а затем дважды для объекта SomeDerivedClass. 2x1 +-= 4