5

階層内のクラスにさまざまな静的初期化を提供しようとしていますが、このコードで試した場合:

#include <iostream>

using namespace std;

struct base {
static const char* componentName;
};
const char* base::componentName = "base";

struct derived : public base {};

const char* derived::componentName = "derived";

int main() {

cout << base::componentName << endl;
cout << derived::componentName << endl;
}

私はこのビルドエラーで終わりました:

test.cpp:15: error: ISO C++ does not permit ‘base::componentName’ to be defined as ‘derived::componentName’
test.cpp:15: error: redefinition of ‘const char* base::componentName’
test.cpp:11: error: ‘const char* base::componentName’ previously defined here

静的初期化は派生クラスでオーバーライドできないようですか?これが機能しない場合は、常にcomponentNameをconst char *を返す静的関数として定義する可能性があります。これに関する唯一の問題は、部分的な特殊化の初期化を行うことを望んでいたことであり、その方法はないようです。ほとんど同じままになる他のすべてのコードをコピーせずに、部分的な特殊化で1つの関数だけを再定義することを知っています。

4

6 に答える 6

5

サブクラスでも宣言する必要があります。

struct derived : public base {
    static const char* componentName;
};
于 2010-11-22T03:13:26.690 に答える
2

静的メンバー変数は、そのクラスのすべてのインスタンスで共有される単一の変数があることを意味します。基本クラスに 1 つの値を設定し、派生クラスに別の値を設定しようとしても機能しません。これは、両方が同じ変数を共有しているためです (当然のことながら、2 つの異なる値を同時に設定することはできません)。

于 2010-11-22T03:31:04.850 に答える
2


その理由は、次のことが当てはまるからだと思います。それらは同じオブジェクトを参照しており、 「最後に笑う人が最もよく笑う」方法で

&base::componentName == &derived::componentName

オブジェクトを2回初期化することは良いことではありません。

乾杯。

ヴィンツ

于 2012-10-02T20:27:51.597 に答える
0

$ 9.4.2 / 2-「名前空間スコープでの定義では、静的データメンバーの名前は、::演算子を使用してそのクラス名で修飾する必要があります。」

と...

静的初期化は派生クラスでオーバーライドできないようですか?

オーバーライドは仮想関数専用であることに注意してください。

$ 10.3 / 2-'仮想メンバー関数vfがクラスBaseおよびBaseから直接または間接的に派生したクラスDerivedで宣言されている場合、Base::vfと同じ名前および同じパラメーターリストを持つメンバー関数vfが宣言されます。次に、Derived :: vfも仮想(そのように宣言されているかどうかに関係なく)であり、97)Base::vfをオーバーライドします。

ポリモルフィックコードを使用する利点を活用しながら、このようにコンポーネント名を再実行してみてください。

struct base{
   virtual char const* myname(){
      return "base";
   }
   virtual ~base(){}
};

struct derived : base{
   virtual char const* myname(){
      return "derived";
   }
};

int main(){}
于 2010-11-22T03:45:11.473 に答える
0

「オーバーライド」と「継承」は、オブジェクトでのみ意味を持つ用語です。クラス変数は、オブジェクトの継承に参加しません。

于 2010-11-22T03:27:17.043 に答える
0

派生クラスで宣言する前に派生クラスで静的変数を初期化しようとすると、派生クラスは基本クラスに似ており、静的変数はクラスに対して 1 回しか定義されていないため、2 回目の初期化で再定義エラーが発生するため、再定義エラーが発生します。

意図したことを行う正しい方法の 1 つを以下に示します。

struct a {
    virtual const string& getClassType() const {
        return ClassName;
    }
    static string ClassName;
};
string a::ClassName = "StructA";

struct c : public a {
    const string& getClassType() const {
        return ClassName;
    }
    static string ClassName;
};
string c::ClassName = "StructC";

a* a1 = new c();
cout << a1->getClassType() << endl;

上記のコードでは、getClassType は仮想関数であり、文字列形式でクラス タイプを返します。この関数は静的変数を使用し、派生クラスでもオーバーライドする必要があります。オーバーライドするのを忘れた場合、コンパイラは関数の基本クラス バージョンを呼び出し、派生クラスの静的変数の代わりに基本クラスの静的変数を使用します。したがって、基本クラスのオブジェクト型が返されます。

于 2014-05-22T06:02:02.230 に答える