¿Se heredan los campos estáticos?

102

Cuando se heredan los miembros estáticos, ¿son estáticos para toda la jerarquía, o solo para 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;
}

¿El total sería 3 en los tres casos, o sería 2 para SomeClassy 1 para SomeDerivedClass?

BartoszKP
fuente

Respuestas:

55

3 en todos los casos, ya que el static int totalheredado por SomeDerivedClasses exactamente el de SomeClass, no una variable distinta.

Editar: en realidad 4 en todos los casos, como @ejames vio y señaló en su respuesta, que ver.

Editar: el código en la segunda pregunta falta inten ambos casos, pero agregarlo lo hace bien, 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, la "oculta" con su propio homónimo uno.

Alex Martelli
fuente
12
Buena explicación, pero la respuesta numérica es en realidad 4, no 3. Vea mi respuesta ( stackoverflow.com/questions/998247/… )
e.James
3
+1, excelente punto, estoy editando la respuesta para señalar la tuya, ¡gracias!
Alex Martelli
1
+1, aunque uno debería decir más correctamente "+4 a lo que sea que se inicialice el miembro estático". El miembro estático no es un ámbito local ni un ámbito de espacio de nombres, por lo que debe haber una definición en algún lugar que asigne un valor ( no necesariamente cero). De lo contrario, el código no cumple con la regla de una definición y no se compilará.
Damon
Pero si uno quiere static int totalser distinto para cada clase derivada, ¿la única forma de lograrlo es agregarlo static int totala cada clase? ¿O es posible usar solo la definición de clase base (?), Porque tener una variable totaldebería ser propiedad de cada clase. Por otro lado, debería serlo static.
LRDPRDX
97

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

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

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

Y los resultados:

A.total = 4
B.total = 4
C.total = 4
e.James
fuente
10

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.

VenuGopal
fuente
5
#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;
}

Podría ser:

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

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. 2x1 + 2 = 4

Darko Maksimovic
fuente
0

3 en los tres casos.

Y para su otra pregunta, parece que realmente solo necesita una variable constante en lugar de estática. Puede resultar más evidente proporcionar una función virtual que devuelva la variable que necesita, que se anula en las clases derivadas.

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

adzm
fuente
0

Sí, la clase derivada contendría la misma variable estática, es decir, todas contendrían 3 para el total (asumiendo que el total se inicializó a 0 en algún lugar).

Niki Yoshiuchi
fuente