2009-06-15 29 views
86

Quando membri statici sono ereditati, sono essi statico per l'intera gerarchia, o solo quella classe, cioè:I campi statici sono ereditati?

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

sarebbe Totale essere 3 in tutti e tre i casi, o sarebbe 2 per SomeClass e 1 per SomeDerivedClass ?

risposta

44

3 in tutti i casi, poiché il static int total ereditato da SomeDerivedClass è esattamente quello in SomeClass, non una variabile distinta.

Modifica: in realtà in tutti i casi, come @james individuato e sottolineato nella sua risposta, che vedono.

Edit: il codice nella seconda questione non è presente il int in entrambi i casi, ma aggiungendo lo rende OK, vale a dire:

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 suo omonimo.

+8

buona spiegazione, ma la risposta numerica è in realtà 4, non 3. Vedere la mia risposta (http: // StackOverflow.it/questions/998247/are-static-members-inherited-c/998298 # 998298) –

+0

+1, punto eccellente, sto modificando la risposta per indicare la tua, grazie! –

+1

+1, anche se si dovrebbe dire più correttamente "+4 a qualunque sia il membro statico inizializzato su". Il membro statico non è né scope locale né scope di namespace, quindi deve esserci una definizione da qualche parte che assegna un valore (_not necessariamente a zero). In caso contrario, il codice non soddisfa la regola a una definizione e non verrà compilato. – Damon

0

3 in tutte e tre le istanze.

E per la tua altra domanda, sembra che tu abbia davvero bisogno solo di una variabile const anziché statica. Potrebbe essere più ovvio fornire al provider una funzione virtuale che restituisce la variabile di cui hai bisogno, che viene sovrascritta nelle classi derivate.

A meno che questo codice non venga chiamato in un percorso critico in cui è necessaria la prestazione, optare sempre per il codice più intuitivo.

0

Sì, la classe derivata conterrebbe la stessa variabile statica, vale a dire - tutti ne contengono 3 per il totale (supponendo che il totale sia stato inizializzato a 0 da qualche parte).

87

La risposta è in realtà quattro in tutti i casi, dopo la costruzione del SomeDerivedClass causerà la totale da incrementare due volte.

Qui è 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 
7

Si tratta di 4 perché quando si crea l'oggetto derivato, il derivato il costruttore della classe chiama il costruttore della classe base.
Quindi il valore della variabile statica viene incrementato due volte.

0

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

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

Sarebbe:

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