静的フィールドは継承されますか?


102

静的メンバーが継承される場合、それらは階層全体に対して静的ですか、それともそのクラスだけですか?

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

3つのインスタンスすべてで合計は3になりますか、それとも2 SomeClassと1 SomeDerivedClassですか?

回答:


55

すべての場合で3。static int total継承されるのSomeDerivedClassはのSomeClass変数であり、明確な変数ではありません。

編集:@ejamesが彼の答えで見つけて指摘したように、実際にはすべてのケースで4です。

編集:2番目の質問のコードにはintどちらの場合もがありませんが、追加すると問題ありません。

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

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

A :: MaxHPとCat :: MaxHPの異なる値で正常に動作します。この場合、サブクラスは基本クラスからstaticを「継承していない」ので、いわば、独自の同名で「非表示」になっています。 1。


12
良い説明が、数値的な答えは、私の答え(表示されない3、実際は4であるstackoverflow.com/questions/998247/...
e.James

3
+1、すばらしいポイント、私はあなたの答えを指すように回答を編集しています。ありがとう!
Alex Martelli、

1
+1。ただし、「静的メンバーが初期化されているものはすべて+4にする」ともっと正確に言うべきです。静的メンバーはローカルスコープでも名前空間スコープでもないため、値(必ずしもゼロではない)を割り当てる定義がどこかになければなりません。そうでない場合、コードはone-definition-ruleを満たさず、コンパイルされません。
デイモン

しかしstatic int total、派生クラスごとに区別したい場合は、それを達成しstatic int totalて各クラスに追加する唯一の方法ですか?または、変数totalを持つことはすべてのクラスのプロパティである必要があるため、基本クラス定義(?)のみを使用することは可能ですか?一方で、それはそうあるべきですstatic
LRDPRDX 2017

97

の構築により合計が2倍になるため、実際の答えはすべての場合で4です。SomeDerivedClass

これが完全なプログラムです(これは私の回答を確認するために使用しました)。

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

そして結果:

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

10

派生オブジェクトが作成されると、派生クラスコンストラクターが基本クラスコンストラクターを呼び出すので、4になります。
したがって、静的変数の値は2回インクリメントされます。


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

それはそのようになります:

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

1

SomeDerivedClass()が呼び出されると、SomeClass()コンストラクターが自動的に呼び出されます。これはC ++ルールです。これが、SomeClassオブジェクトごとに1回、SomeDerivedClassオブジェクトごとに2回合計が増加する理由です。2x1 + 2 = 4


0

3つのインスタンスすべてで3。

そして、他の質問については、静的ではなくconst変数が本当に必要なようです。派生クラスでオーバーライドされる必要な変数を返す仮想関数を提供する方がわかりやすいかもしれません。

このコードがパフォーマンスが必要なクリティカルパスで呼び出されない限り、常により直感的なコードを選択してください。


0

はい、派生クラスには同じ静的変数が含まれます。つまり、それらにはすべて合計で3が含まれます(合計がどこかで0に初期化されていると想定)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.