Os campos estáticos são herdados?

102

Quando os membros estáticos são herdados, eles são estáticos para toda a hierarquia ou apenas para essa classe, ou seja:

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

o total seria 3 em todas as três instâncias ou seria 2 para SomeClasse 1 para SomeDerivedClass?

BartoszKP
fonte

Respostas:

55

3 em todos os casos, uma vez que o static int totalherdado por SomeDerivedClassé exatamente aquele em SomeClass, não uma variável distinta.

Edit: na verdade 4 em todos os casos, como @ejames notou e apontou em sua resposta, que ver.

Editar: o código na segunda pergunta está faltando intem ambos os casos, mas adicioná-lo o torna OK, ou seja:

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

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

funciona bem e com valores diferentes para A :: MaxHP e Cat :: MaxHP - neste caso a subclasse "não está herdando" a estática da classe base, pois, por assim dizer, está "escondendo-a" com seu próprio homônimo 1.

Alex Martelli
fonte
12
Boa explicação, mas a resposta numérica é na verdade 4, não 3. Veja minha resposta ( stackoverflow.com/questions/998247/… )
e.James
3
+1, Excelente ponto, estou editando a resposta para apontar para a sua, obrigado!
Alex Martelli
1
+1, embora se deva dizer mais corretamente "+4 para o que quer que o membro estático seja inicializado". O membro estático não é um escopo local nem um escopo de namespace, portanto, deve haver uma definição em algum lugar que atribua um valor ( não necessariamente zero). Caso contrário, o código não cumpre a regra de uma definição e não compilará.
Damon
Mas se alguém quiser static int totalser distinto para cada classe derivada, a única maneira de alcançá-lo é adicionar static int totala cada classe? Ou é possível usar apenas a definição de classe base (?), Porque ter variável totaldeve ser propriedade de todas as classes. Por outro lado, deve ser static.
LRDPRDX de
97

Na verdade, a resposta é quatro em todos os casos, pois a construção de SomeDerivedClassfará com que o total seja incrementado duas vezes .

Aqui está um programa completo (que usei para verificar minha resposta):

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

E os resultados:

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

É 4 porque quando o objeto derivado é criado, o construtor da classe derivada chama o construtor da classe base.
Portanto, o valor da variável estática é incrementado duas vezes.

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

Seria:

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

O construtor SomeClass () está sendo chamado automaticamente quando SomeDerivedClass () é chamado, esta é uma regra C ++. É por isso que o total é incrementado uma vez para cada objeto SomeClass e, em seguida, duas vezes para o objeto SomeDerivedClass. 2x1 + 2 = 4

Darko Maksimovic
fonte
0

3 em todos os três casos.

E para sua outra pergunta, parece que você realmente só precisa de uma variável const em vez de estática. Pode ser mais autoexplicativo fornecer uma função virtual que retorna a variável de que você precisa, que é substituída nas classes derivadas.

A menos que esse código seja chamado em um caminho crítico onde o desempenho é necessário, sempre opte pelo código mais intuitivo.

adzm
fonte
0

Sim, a classe derivada conteria a mesma variável estática, ou seja, todas conteriam 3 para o total (assumindo que o total foi inicializado em 0 em algum lugar).

Niki Yoshiuchi
fonte