C では、virtual キーワードを使用して関数メンバーを定義する場合、その関数が仮想関数であり、サブクラスによってオーバーライドできることを意味します。ただし、データ メンバー (つまり属性) を仮想として定義すると、C コンパイラはエラーを報告します。仮想メンバーは静的または非静的データ メンバーにすることはできません。
では、なぜ仮想をデータ メンバーに使用できないのでしょうか?仮想関数と非仮想関数の違いは、仮想関数は関数テーブルを通じてアクセスされるのに対し、データ メンバーは直接アクセスされることです。データ メンバーを仮想として定義すると、仮想関数が見つからないため、プログラムはエラーになります。
では、サブクラス内のメンバー変数を本当にオーバーライドする必要がある場合はどうすればよいでしょうか? C11 で導入された新機能である仮想継承を使用できます。仮想継承は、多重継承の複雑さを軽減し、いくつかの問題を解決できる特別な継承方法です。仮想継承では、基本クラスのコンストラクターは 1 回だけ呼び出されるため、複数の初期化によって引き起こされる問題が回避されます。
次は、仮想継承を使用してオーバーライド メンバー変数を実装するサンプル コードです:
class Base { public: virtual int& getVar() { return var; } protected: int var; }; class Derived : virtual public Base { public: virtual int& getVar() { return var; } protected: int var; }; int main() { Base* b = new Derived(); b->getVar() = 42; cout << b->getVar() << endl; return 0; }
このサンプル コードでは、基本クラス Base と派生クラス Derived を定義します。 Base クラスには整数変数 var があり、これを仮想型として定義します。この変数にアクセスすることはできませんが、この関数は派生クラスで書き換えるための基底クラスとして使用できます。 Derived クラスには var という名前の整数変数もあり、Base の getVar() 関数をオーバーライドして、Base の関数をカバーします。 main 関数では、Derived のインスタンスを作成し、基本クラス ポインター b でそれをポイントし、getVar() 関数を通じてアクセスします。出力は42です。
仮想継承を使用すると、派生クラスの基本クラスにある var という名前のメンバー変数をオーバーライドし、この変数の値にアクセスして、関数のオーバーライドと同様の操作を実現できます。
要約すると、C の virtual キーワードは関数にのみ使用でき、データ メンバーには使用できません。サブクラス内のメンバー変数をオーバーライドする場合は、仮想継承を使用できます。仮想継承により、複数の初期化の問題を回避でき、基本クラスでオーバーライドされたメンバー変数にアクセスできます。
以上がC++ 構文エラー: 仮想メンバーを静的データ メンバーまたは非静的データ メンバーにすることはできません。どうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。