23774


下記のコードを考えたとき、hogeを継承したhoge2からhogeのpublic member
functionを呼び出せるはずですが、hoge2でhoge_function()を定義して、hoge_function(bool)を呼び出そうとするとvisual
studioではC2660、clangではtoo many argumentsのエラーが出てしまいます。

なぜこのような挙動をするのでしょうか？

参考ですが、hoge2のhoge_function(bool)を削除すれば、エラーがなくなります。

追記：  
コメントを参考に以下のように質問のコードを修正しました。

[code]

    #include<iostream>
    #include<memory>
    class hoge
    {
    public:
    
        virtual void hoge_function()
        {
            std::cout << "hoge" << std::endl;
        }
    
        //virtual void hoge_function(bool hoge = true)
        virtual void hoge_function(bool hoge)
        {
            std::cout << "hogehoge" << std::endl;
        }
    };
    
    class hoge2 : public hoge
    {
    public:
        //virtual void hoge_function()
        virtual void hoge_function(bool hoge)
        {
            std::cout << "hoge2" << std::endl;
        }
    };
    
    int main()
    {
        std::shared_ptr<hoge2> hogehoge = std::make_shared<hoge2>();
    
        // this line returns an error
        hogehoge->hoge_function(true);
    
        return 0;
    }
    
[/code]


CC BY-SA 3.0
2016-04-06T00:43:18.553
23772
2016-04-06T13:08:12.970
2016-04-06T13:08:12.970
question
c++
public inheritanceのエラー


`using hoge::hoge_function;`というのを`hoge2`の側に追加すると期待の動作にすることができるようです。

[code]

    class hoge2 : public hoge
    {
    public:
        using hoge::hoge_function;
        virtual void hoge_function()
        {
            std::cout << "hoge2" << std::endl;
        }
    };
    
[/code]

C++のシンボル名解決とoverloading解決の手順は、

  1. 直近のscopeでシンボル名を解決する
  2. 解決されたscopeの範囲でoverloadingを解決する(継承関係は遡らない)

と言う形になるそうです。

従ってご所望の形でoverloadingを解決したければ、`hoge_function`が定義されたscope内に他の全てのoverloadも取り込んでおけば良い、と言うことらしいです。

以上本家の[Overriding a Base's Overloaded Function in
C++](https://stackoverflow.com/questions/888235/overriding-a-bases-overloaded-
function-in-c)とduplicate元とされている記事を参考にしました。("c++ overriding overloaded
function"での検索結果をたどってます。)


CC BY-SA 3.0
2016-04-06T01:10:54.937
23774
2016-04-06T01:10:54.937
2017-05-23T12:38:56.083
-1
13972
23772
answer


[c++](/questions/tagged/c%2b%2b "'c++' のタグが付いた質問を表示") 言語規格書上、  
ソースコード上の型を 静的な型 と呼び、実際のオブジェクトの型を 動的な型 と呼びます。

[code]

    struct base { ... };
    struct derived : base { ... };
    base* p=new derived;
    
[/code]

このとき `*p` の静的な型は `base` 動的な型は `derived` ということになります。

関数呼び出しにおける多重定義解決は、呼ばれる関数が `virtual` であってもなくても  
静的な型に対して行われることになっています（5.2.2 関数呼び出しの 1 の後ろのほう）  
多重定義解決の続きは既に解説があるとおりなので省略。

あと提示例では `virtual` な関数に対してデフォルト引数を使っています。  
デフォルト引数の値の解決も静的な型で行われるので注意が必要です。  
(8.3.6 省略時引数の 10)

[code]

    struct base { virtual void f(int x=1); }
    struct derived : base { virtual void f(int x=2); }
    struct derived2 : derived { virtual void f(int x); }
    derived2* p=new derived2;
    p->f(); // コンパイルエラー : デフォルト引数は無い
    derived* q=p;
    q->f(); // 呼べて、採用される値は 2 である
    base* r=p;
    r->f(); // 呼べて、採用される値は 1 である
    
[/code]

混乱の元なのでウチの運用では `virtual` な関数に異なるデフォルト引数を使うことは禁じています。


CC BY-SA 3.0
2016-04-06T01:57:03.143
23775
2016-04-06T04:03:34.927
2016-04-06T04:03:34.927
8589
8589
23772
answer