Унаследованы статические поля?
Когда статические члены наследуются, являются ли они статическими для всей иерархии или только для этого класса, то есть:
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