I campi statici vengono ereditati?


102

Quando i membri statici vengono ereditati, sono statici per l'intera gerarchia o solo per quella classe, ovvero:

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

il totale sarebbe 3 in tutti e tre i casi, o sarebbe 2 per SomeClasse 1 per SomeDerivedClass?

Risposte:


55

3 in tutti i casi, poiché l' static int totalereditata da SomeDerivedClassè esattamente quella in SomeClass, non una variabile distinta.

Modifica: in realtà 4 in tutti i casi, come @ejames ha notato e sottolineato nella sua risposta, che vedi.

Modifica: il codice nella seconda domanda manca intin entrambi i casi, ma aggiungerlo lo rende OK, ovvero:

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

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

funziona bene e con valori diversi per A :: MaxHP e Cat :: MaxHP - in questo caso la sottoclasse "non eredita" la statica dalla classe base, poiché, per così dire, la "nasconde" con il proprio omonimo uno.


12
Buona spiegazione, ma la risposta numerica è in realtà 4, non 3. Vedere la mia risposta ( stackoverflow.com/questions/998247/... )
e.James

3
+1, punto eccellente, sto modificando la risposta per indicare la tua, grazie!
Alex Martelli

1
+1, anche se si dovrebbe dire più correttamente "+4 a qualunque sia il membro statico inizializzato". Il membro statico non è né ambito locale né ambito dello spazio dei nomi, quindi deve esserci una definizione da qualche parte che assegni un valore ( non necessariamente zero). Altrimenti il ​​codice non soddisfa la regola di una definizione e non verrà compilato.
Damon

Ma se si vuole static int totalessere distinti per ogni classe derivata l'unico modo per ottenerlo da aggiungere static int totalad ogni classe? Oppure è possibile utilizzare solo la definizione della classe di base (?), Perché avere una variabile totaldovrebbe essere la proprietà di ogni classe. D'altra parte dovrebbe essere static.
LRDPRDX

97

La risposta è in realtà quattro in tutti i casi, poiché la costruzione di SomeDerivedClassfarà aumentare il totale due volte .

Ecco un programma completo (che ho usato per verificare la mia risposta):

#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 i risultati:

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

10

È 4 perché quando viene creato l'oggetto derivato, il costruttore della classe derivata chiama il costruttore della classe base.
Quindi il valore della variabile statica viene incrementato due volte.


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

Sarebbe:

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

1

Il costruttore SomeClass () viene chiamato automaticamente quando viene chiamato SomeDerivedClass (), questa è una regola C ++. Ecco perché il totale viene incrementato una volta per ogni oggetto SomeClass e quindi due volte per l'oggetto SomeDerivedClass. 2x1 + 2 = 4


0

3 in tutti e tre i casi.

E per l'altra tua domanda, sembra che tu abbia davvero bisogno di una variabile const invece di statica. Potrebbe essere più autoesplicativo fornire una funzione virtuale che restituisca la variabile necessaria che viene sovrascritta nelle classi derivate.

A meno che questo codice non venga chiamato in un percorso critico in cui le prestazioni sono necessarie, optare sempre per il codice più intuitivo.


0

Sì, la classe derivata conterrebbe la stessa variabile statica, cioè - conterrebbero tutti 3 per total (supponendo che total sia stato inizializzato a 0 da qualche parte).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.