3
  1. 最初のケース

    #include <iostream>
    class A
    {
    public:
        virtual void Write(int i)
        {
            std::wcout << L"Write(int) is called" << std::endl;
        }
        virtual void Write(wchar_t c)
        {
            std::wcout << L"Write(wchar_t) is called" << std::endl;
        }
    };
    int _tmain(int argc, wchar_t* argv[])
    {
        A *p = new A();
        int i = 100;
        p->Write(i);
        return 0;
    }
    

完璧に動作します。
プログラム出力
Write(int) が呼び出される

2.2番目のケース。
最初の関数を基本クラスに移動するだけです:

#include <iostream>
class Base
{
public:
   virtual void Write(int i)
   {
       std::wcout << L"Base::Write(int) is called" << std::endl;
   }
};
class Derived: public Base
{
public:
    virtual void Write(wchar_t c)
    {
        std::wcout << L"Derived::Write(wchar_t) is called" << std::endl;
    }
};
int _tmain(int argc, wchar_t* argv[])
{
    Derived *p = new Derived();
    int i = 100;
    p->Write(i);
    return 0;
}

プログラム出力
Derived::Write(wchar_t) が呼び出されまし
たが 、「Base::Write(int) が呼び出された」と予想
しました。

4

2 に答える 2

4

あなたのコンパイラは正しいです。

派生クラスでメンバー関数を定義すると、基底クラスで同じ名前のメンバー関数が非表示になります。

usingそれを派生クラスのスコープにインポートするために使用でき、オーバーロードを期待どおりに機能させることができます。

class Derived: public Base
{
public:
    using Base::Write;
    virtual void Write(wchar_t c)
    {
        std::wcout << L"Derived::Write(wchar_t) is called" << std::endl;
    }
};

編集

関数のオーバーロードは、異なるスコープを通過しません。Writeonを呼び出すとDerived、名前の付いたメンバー関数がクラス スコープでWrite検出され、名前の検索が停止するため、ここでは基本クラスのバージョンの方が適切であっても、 inがオーバーロードの解決と見なされることはありません。DerivedWriteBase

名前検索を参照してください

于 2016-02-13T15:02:51.147 に答える
0

プログラムが暗黙的な変換で正しい「新しい」バージョンの関数を見つけたためだと思います。そのため、親クラスで呼び出す「より良い」関数を探しません。私はお勧めします:1)交換可能なパラメータで関数をオーバーロード/再定義しないでください。2) Derived::Write を本当に呼び出したい場合は、以下を使用します。

 p->Derived::Write(i);
于 2016-02-13T15:01:56.863 に答える