¿Son heredados los campos estáticos?

Cuando los miembros estáticos se heredan, son estáticos para toda la jerarquía, o simplemente esa clase, es decir:

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; } 

totalizaría 3 en las tres instancias, o serían 2 para SomeClass y 1 para SomeDerivedClass ?

3 en todos los casos, ya que el static int total heredado por SomeDerivedClass es exactamente el de SomeClass , no una variable distinta.

Editar: en realidad 4 en todos los casos, como @ejames detectados y señalados en su respuesta, que ven.

Editar: al código en la segunda pregunta le falta el int en ambos casos, pero agregarlo lo hace correcto, es decir:

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

funciona bien y con diferentes valores para A :: MaxHP y Cat :: MaxHP; en este caso, la subclase “no hereda” la estática de la clase base, ya que, por así decirlo, está “ocultándola” con su propio homónimo uno.

La respuesta es en realidad cuatro en todos los casos, ya que la construcción de SomeDerivedClass hará que el total se incremente dos veces .

Aquí hay un progtwig completo (que usé para verificar mi respuesta):

 #include  #include  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; } 

Y los resultados:

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

Es 4 porque cuando se crea el objeto derivado, el constructor de la clase derivada llama al constructor de la clase base.
Entonces, el valor de la variable estática se incrementa dos veces.

 #include 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; } 

Podría ser:

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

El constructor SomeClass () se llama automáticamente cuando se llama SomeDerivedClass (), esta es una regla de C ++. Es por eso que el total se incrementa una vez por cada objeto SomeClass, y luego dos veces para el objeto SomeDerivedClass. 2×1 + 2 = 4

3 en las tres instancias.

Y para su otra pregunta, parece que realmente solo necesita una variable constante en lugar de estática. Puede ser más fácil de explicar el proveedor de una función virtual que devuelve la variable que necesita que se reemplaza en las clases derivadas.

A menos que se llame a este código en una ruta crítica donde el rendimiento es necesario, siempre opte por el código más intuitivo.

Sí, la clase derivada contendría la misma variable estática, es decir, todas contendrían 3 para el total (suponiendo que el total se inicializara a 0 en alguna parte).