web-dev-qa-db-fra.com

Les champs statiques sont-ils hérités?

Lorsque les membres statiques sont hérités, sont-ils statiques pour toute la hiérarchie, ou juste pour cette classe, à savoir:

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

le total serait-il de 3 dans les trois cas, ou serait-ce 2 pour SomeClass et 1 pour SomeDerivedClass?

94
user98188

3 dans tous les cas, puisque le static int total hérité par SomeDerivedClass est exactement celui de SomeClass, pas une variable distincte.

Edit: en fait 4 dans tous les cas, comme @ejames l'a repéré et souligné dans sa réponse, qui voit.

Edit: le code dans la deuxième question ne contient pas le int dans les deux cas, mais l'ajouter le rend OK, c'est-à-dire:

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

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

fonctionne bien et avec des valeurs différentes pour A :: MaxHP et Cat :: MaxHP - dans ce cas, la sous-classe "n'hérite pas" de la statique de la classe de base, car, pour ainsi dire, elle la "cache" avec son propre homonyme une.

49
Alex Martelli

La réponse est en fait quatre dans tous les cas, car la construction de SomeDerivedClass entraînera l'incrémentation du total deux fois.

Voici un programme complet (que j'ai utilisé pour vérifier ma réponse):

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

Et les résultats:

A.total = 4
B.total = 4
C.total = 4
93
e.James

Il s'agit de 4 car lorsque l'objet dérivé est créé, le constructeur de classe dérivée appelle le constructeur de classe de base.
La valeur de la variable statique est donc incrémentée deux fois.

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

Ce serait:

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

Le constructeur SomeClass () est appelé automatiquement lorsque SomeDerivedClass () est appelé, il s'agit d'une règle C++. C'est pourquoi le total est incrémenté une fois pour chaque objet SomeClass, puis deux fois pour certains objets SomeDerivedClass. 2x1 + 2 = 4

1
Darko Maksimovic

3 dans les trois cas.

Et pour votre autre question, il semble que vous ayez vraiment besoin d'une variable const au lieu de statique. Il peut être plus explicite de fournir une fonction virtuelle qui renvoie la variable dont vous avez besoin qui est remplacée dans les classes dérivées.

À moins que ce code ne soit appelé dans un chemin critique où les performances sont nécessaires, optez toujours pour le code plus intuitif.

0
adzm

Oui, la classe dérivée contiendrait la même variable statique, c'est-à-dire qu'elles contiendraient toutes 3 pour le total (en supposant que le total a été initialisé à 0 quelque part).

0
Niki Yoshiuchi