2016-12-01 3 views
6

私は誤って、基本構造体によって派生したクラスのprivateメンバーを持つ(基本)構造体の一部のメンバ変数をシャドウしました。コンパイラは、派生クラスでシャドーされたベース構造体のメンバ変数について警告を出すべきではありませんか?

構造体{
int a;
INT;
}

派生クラス:プライベート公衆基地{
(テスト中幸運にもキャッチ)卑劣なバグを引き起こして、私の場合は間違いだった
...


私はシャドウイングのメンバーが本当にまれだと思っています(悪い練習とはみなされない場合)。なぜコンパイラーが少なくとも警告を出さないのだろうか?(シャドーイングは合法的に許可されているので、

私が使用したコンパイラは、Microsoft Visual C++ 2015、警告レベル4です。
他のコンパイラ(つまりGCC)がこのような状況に対して特定の警告を出すのではないかと思いますか?

+0

gccも警告を出すわけではありませんが、この動作がポリモーフィズムで全体的にどのように機能するのでしょうか。 – Starl1ght

+1

あなたの例のような変数をシャドーイングすると、たとえprivateでもなくてもほとんど間違いです。私は[clang](https://llvm.org/bugs/show_bug.cgi?id=31222)と[gcc](https://gcc.gnu.org/bugzilla/show_bug.cgi?)の両方の機能リクエストを提出しました。 id = 78632)。 –

+1

@VittorioRomeo 'Derived'が書かれた時点で' Base'に 'a'が存在しなかったのは間違いではありません。 –

答えて

4

シャドウイングが不良かどうかは、競合する名前を導入した順序によって異なります。

struct Base { 
    int a; 
}; 

その後、自分のクラスライブラリを使用している顧客Aがこれを書き込みます:この場合

class DerivedA : public Base { 
private: 
    int a; 
}; 

を使用すると、クラスライブラリを持っている、とクラスの一つがこれですと仮定しますシャドーイングはおそらく意図しないものです。顧客が誤ってBase::aをシャドーしました。

しかし、あなたもこれを書き込み、顧客Bを、持っているとします

class DerivedB : public Base { 
private: 
    int b; 
}; 

これまでのところは良いです。今度はBaseオブジェクトを使用するようにライブラリを構築し、ライブラリを使用する顧客BはBaseDerivedBオブジェクトの両方を使用するコードの本体を構築します。

数週間後、新しい機能を追加するには、Baseに新しいメンバーを追加する必要があることを認識しています。

struct Base { 
    int a; 
    int b; // new member variable 
}; 

これでライブラリに問題がありますか?顧客Bに問題が生じますか?

いいえ、問題は発生しません。

BaseBaseを使用し続けます、そしてそれは空想の新しいb機能を取得するためにbメンバーを使用することができます使用して、あなたのコードのすべて。 DerivedBオブジェクトがBaseが必要な関数に渡されても、Derivedがシャドーイングするという事実はBaseには影響しません。Baseを使用する関数はbと表示され、Baseメンバ変数にアクセスします。

一方、DerivedBDerivedBを使用し続けます使用しており、そのコードがbを言うとき、それは以前と同じように、DerivedB::bを取得し、顧客Bのコードのすべて。 Phew、シャドーイングがその日を救った!

(もちろん、顧客Bが新しいb機能を利用したい場合、顧客Bは競合を解決するために余分な作業を行う必要がありますが、重要なのはシャドーイングが新しい問題を作成しなかったことです

シャドウイングが良いか悪いかは、競合する名前を導入した順序によって決まります。これはコンパイラが洞察するものではありません。

+1

これはコンパイラが洞察しているものではありませんが、コンパイラが簡単に警告できるヒューマンエラーになる可能性があります。 派生クラスの開発者がシャドーイングを意図している場合、警告を無視または抑制することがあります。 これらのケースでは、私は望ましくない動作より多くの警告を好むでしょう... – roalz

+0

@roalzしかし、ライブラリ作成者は、ライブラリ自体に警告抑制を導入していますか?警告は顧客Bのコードに由来し、図書館の著者は顧客Bのコードにアクセスできません。 –

+0

IMHOでは、「顧客」コードにシャドーイング(欲しいかどうか)が導入されているため、警告を抑止するのは顧客の責任です。または私は何かを逃していますか? – roalz

関連する問題