

タイトルがわかりにくい言葉になってて申し訳ないです。  
実際の処理とは違うのですが、

[code]

    class Parent
    {
    protected:
        int max = 10;
    
    public:
        void func()
        {
            for (int i = 0; i < max; i++)
            {
                printf("文字列");
            }
        }
    };
    
    class Child : public Parent
    {
        int max = 20;
    };
    
[/code]

のような処理を書いた場合に、このヘッダ(実際にはヘッダとソースで分けてあるので)をincludeし、

[code]

    Child hoge;
    hoge.func()
    
[/code]

のような処理をした場合、Childのmaxは無視され、Parentが本来もっているmaxが使われます。  
処理自体はParentと同じ、ただ同じ名前・同じ型の変数のChildで持っている変数を使わせて処理を行いたい、という場合はどうすればいいのでしょうか?


CC BY-SA 3.0
2015-12-20T00:00:52.487
20189
2015-12-20T01:40:40.867
2015-12-20T00:32:56.833
13742
13742
question
c++
C++でクラスの実装について


`protected:`なので書き換えちゃうのが手っ取り早いかと  
maxが同じ数になっていて実行結果でわかりにくいので別々の数値のほうがわかりやすいと思います。


CC BY-SA 3.0
2015-12-20T00:08:12.047
20190
2015-12-20T00:08:12.047
13656
20189
answer


ParentのmaxとChildのmaxは実体としては別のフィールド扱いになります。Childのメンバ関数からmaxを参照するとスコープの関係でChildのmaxが見えますが、Parentのmaxも別に存在していてParent::maxとして参照可能です。Parentのメンバ関数はParentのスコープでmaxを解決するので、常にParent::maxを参照してしまいます。

子クラスで値を変えたい場合は、他の回答にあるように書き換えるか、getterをvirtualにして子クラスでオーバライドするかです。


CC BY-SA 3.0
2015-12-20T00:54:55.007
20192
2015-12-20T00:54:55.007
5258
20189
answer


宣言による変数の上書きはできません。それを行うには`virtual`関数が必要になります。

[code]

    class Parent
    {
    protected:
        int virtual max(){ return 10; }
    
    public:
        void func()
        {
            for (int i = 0; i < max(); i++)
            {
                printf("文字列");
            }
        }
    };
    
    class Child : public Parent
    {
        int max(){ return 20; }
    };
    
[/code]

ですがuser13656さんも指摘されているように変数であればコンストラクターなどで上書きしてしまえばいいでしょう。

[code]

    class Parent
    {
    protected:
        int max = 10;
    
    public:
        void func()
        {
            for (int i = 0; i < max; i++)
            {
                printf("文字列");
            }
        }
    };
    
    class Child : public Parent
    {
    public:
        Child(){ max = 20; }
    };
    
[/code]

しかしこれではmaxの値が分りづらいです。どうせコンストラクターで処理するのであれば値を渡してしまうこともできます。

[code]

    class Parent
    {
    protected:
        int max;
        Parent(int max): max(max){}
    
    public:
        Parent(): max(10){}
        void func()
        {
            for (int i = 0; i < max; i++)
            {
                printf("文字列");
            }
        }
    };
    
    class Child : public Parent
    {
    public:
        Child(): Parent(20){}
    };
    
[/code]

でも最近のC++言語では`virtual`や継承は使わずに`template`を使ったりもします。

[code]

    template<int max = 10>
    class Parent
    {
    public:
        void func()
        {
            for (int i = 0; i < max; i++)
            {
                printf("文字列");
            }
        }
    };
    
    class Child: public Parent<20>{};
    
[/code]

等々、方法はいろいろありますので、状況にあった選択をしてください。


CC BY-SA 3.0
2015-12-20T01:40:40.867
20195
2015-12-20T01:40:40.867
4236
20189
answer