Werden statische Felder vererbt?

102

Wenn statische Elemente geerbt werden, sind sie statisch für die gesamte Hierarchie oder nur für diese Klasse, dh:

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

wäre insgesamt 3 in allen drei Fällen oder wäre es 2 für SomeClassund 1 für SomeDerivedClass?

BartoszKP
quelle

Antworten:

55

3 in allen Fällen, da das static int totalgeerbte von SomeDerivedClassgenau das in ist SomeClass, keine eindeutige Variable.

Edit: eigentlich 4 in allen Fällen, wie @ejames in seiner Antwort entdeckt und hervorgehoben hat, die sehen.

Bearbeiten: Der Code in der zweiten Frage fehlt intin beiden Fällen, aber das Hinzufügen macht es OK, dh:

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

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

funktioniert gut und mit unterschiedlichen Werten für A :: MaxHP und Cat :: MaxHP - in diesem Fall "erbt" die Unterklasse die Statik nicht von der Basisklasse, da sie sie sozusagen mit ihrem eigenen Homonymen "versteckt" einer.

Alex Martelli
quelle
12
Gute Erklärung, aber die numerische Antwort ist tatsächlich 4, nicht 3. Siehe meine Antwort ( stackoverflow.com/questions/998247/… )
e.James
3
+1, Ausgezeichneter Punkt, ich bearbeite die Antwort, um auf Ihre zu zeigen, danke!
Alex Martelli
1
+1, obwohl man korrekter sagen sollte "+4 zu was auch immer das statische Element initialisiert wird". Das statische Element ist weder ein lokaler Bereich noch ein Namespace-Bereich. Daher muss irgendwo eine Definition vorhanden sein, die einen Wert zuweist ( nicht unbedingt Null). Andernfalls erfüllt der Code nicht die One-Definition-Regel und wird nicht kompiliert.
Damon
Aber wenn man static int totalfür jede abgeleitete Klasse unterschiedlich sein möchte , ist der einzige Weg, dies zu erreichen, static int totalzu jeder Klasse hinzuzufügen ? Oder ist es möglich, nur die Basisklassendefinition (?) Zu verwenden, da eine Variable totaldie Eigenschaft jeder Klasse sein sollte. Auf der anderen Seite sollte es sein static.
LRDPRDX
97

Die Antwort ist tatsächlich vier in allen Fällen, da die Konstruktion von SomeDerivedClassbewirkt, dass die Summe zweimal erhöht wird .

Hier ist ein vollständiges Programm (mit dem ich meine Antwort überprüft habe):

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

Und die Ergebnisse:

A.total = 4
B.total = 4
C.total = 4
James
quelle
10

Es ist 4, da der abgeleitete Klassenkonstruktor beim Erstellen des abgeleiteten Objekts den Basisklassenkonstruktor aufruft.
Der Wert der statischen Variablen wird also zweimal erhöht.

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

Es wäre:

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

Der SomeClass () -Konstruktor wird automatisch aufgerufen, wenn SomeDerivedClass () aufgerufen wird. Dies ist eine C ++ - Regel. Aus diesem Grund wird die Summe einmal pro SomeClass-Objekt und dann zweimal für SomeDerivedClass-Objekte erhöht. 2x1 + 2 = 4

Darko Maksimovic
quelle
0

3 in allen drei Fällen.

Und für Ihre andere Frage sieht es so aus, als ob Sie wirklich nur eine konstante Variable anstelle einer statischen benötigen. Es kann selbsterklärender sein, eine virtuelle Funktion bereitzustellen, die die benötigte Variable zurückgibt, die in abgeleiteten Klassen überschrieben wird.

Wenn dieser Code nicht in einem kritischen Pfad aufgerufen wird, in dem Leistung erforderlich ist, wählen Sie immer den intuitiveren Code.

adzm
quelle
0

Ja, die abgeleitete Klasse würde dieselbe statische Variable enthalten, dh sie würde alle 3 für total enthalten (vorausgesetzt, total wurde irgendwo auf 0 initialisiert).

Niki Yoshiuchi
quelle