2016-04-03 13 views
3

私は多くの議論で、protectedのクラスメンバーが悪いことを読んだので、その理由が分かります。しかし、下の例では、const int ageprivateを作成し、その問題を解決する最もエレガントな方法は何ですか?保護されたクラスメンバーを避けるにはどうすればいいですか?

#include <iostream> 

class Animal 
{ 
    public: 
     Animal(const int age) : age(age) {} 
     void print_age() const { std::cout << age << std::endl; } 
    protected: 
     const int age; 
}; 

class Dog : public Animal 
{ 
    public: 
     Dog(const int age) : Animal(age) {} 
     void bark() const 
     { 
      if (age >= 1) 
       std::cout << "Woof!" << std::endl; 
      else 
       std::cout << "(...)" << std::endl; 
     } 
}; 

int main() 
{ 
    Dog dog(1); 
    dog.print_age(); 
    dog.bark(); 
    return 0; 
} 
+0

'int getAge()const {return age; } '? – Default

+0

'age'を非公開にした場合、アクセサ(getとset)を追加する必要があります。しかし、あなたはそれを公開させますか?年齢は動物の階層の外側で修正されるはずですか?もしそうでなければ、あなたはそれを保護させなければなりません、そして、あなたは同じ問題に戻ります。 –

+0

@Default、アクセサー関数を使用して基本クラスから変数を取得するのは奇妙なことではありませんか? – Chiel

答えて

6

あなたは、このようなWhy is Clean Code suggesting avoiding protected variables?のような理由に言及している場合、あなたはまた、これらのガイドラインは、継承階層は、動物や犬のように皆伐されないことが多い現実の世界のシナリオ、のために意図されていることを心に留めておく必要があります。エンタープライズレベルのアプリケーションでは、多くの開発者が継承の点で将来的に組織を増やすかのように考えることを魅力的ですが、実際には変数は無意識のうちに基底クラスに投げ込まれ、時間の経過とともに構造が肥大化し、そのメンバーの。

あなたの単純なケースでは、protectedを使用すると問題ありません。

+0

私の解決策は理にかなっています。単純な構造のプログラムでは、私が使っている方法で 'protected'を使うのは問題ありませんか? – Chiel

+0

です。より大きなアプリケーションの文脈では、どのように意味をなさないのかの例は、近い将来にDog以外の動物をサポートする必要がなければ、あなたは「年齢」と他のメンバーをベースに置くことですクラス。もちろん、その場合には、「動物」を作成するべきではありません。 (この例をより現実的なものに類推するのはちょっと難しいです。) –

+0

私がこれらの概念を適用するコードには、他の「動物」があります。私は、人々がSOに関する議論でしばしば非常に独断的であることが奇妙であることを知っています(これが私がこの質問を開いた理由です)。保護されたメンバーが問題につながる最小限の例を持つことは素晴らしいことです。 – Chiel