シャドウイングが不良かどうかは、競合する名前を導入した順序によって異なります。
struct Base {
int a;
};
その後、自分のクラスライブラリを使用している顧客Aがこれを書き込みます:この場合
class DerivedA : public Base {
private:
int a;
};
、
を使用すると、クラスライブラリを持っている、とクラスの一つがこれですと仮定しますシャドーイングはおそらく意図しないものです。顧客が誤ってBase::a
をシャドーしました。
しかし、あなたもこれを書き込み、顧客Bを、持っているとします
class DerivedB : public Base {
private:
int b;
};
これまでのところは良いです。今度はBase
オブジェクトを使用するようにライブラリを構築し、ライブラリを使用する顧客BはBase
とDerivedB
オブジェクトの両方を使用するコードの本体を構築します。
数週間後、新しい機能を追加するには、Base
に新しいメンバーを追加する必要があることを認識しています。
struct Base {
int a;
int b; // new member variable
};
これでライブラリに問題がありますか?顧客Bに問題が生じますか?
いいえ、問題は発生しません。
Base
がBase
を使用し続けます、そしてそれは空想の新しいb
機能を取得するためにb
メンバーを使用することができます使用して、あなたのコードのすべて。 DerivedB
オブジェクトがBase
が必要な関数に渡されても、Derived
がシャドーイングするという事実はBase
には影響しません。Base
を使用する関数はb
と表示され、Base
メンバ変数にアクセスします。
一方、DerivedB
はDerivedB
を使用し続けます使用しており、そのコードがb
を言うとき、それは以前と同じように、DerivedB::b
を取得し、顧客Bのコードのすべて。 Phew、シャドーイングがその日を救った!
(もちろん、顧客Bが新しいb
機能を利用したい場合、顧客Bは競合を解決するために余分な作業を行う必要がありますが、重要なのはシャドーイングが新しい問題を作成しなかったことです
シャドウイングが良いか悪いかは、競合する名前を導入した順序によって決まります。これはコンパイラが洞察するものではありません。
gccも警告を出すわけではありませんが、この動作がポリモーフィズムで全体的にどのように機能するのでしょうか。 – Starl1ght
あなたの例のような変数をシャドーイングすると、たとえprivateでもなくてもほとんど間違いです。私は[clang](https://llvm.org/bugs/show_bug.cgi?id=31222)と[gcc](https://gcc.gnu.org/bugzilla/show_bug.cgi?)の両方の機能リクエストを提出しました。 id = 78632)。 –
@VittorioRomeo 'Derived'が書かれた時点で' Base'に 'a'が存在しなかったのは間違いではありません。 –