5

プロジェクトで次のコードを見ました。

class Base
{
...
    virtual double Function(int i) const;

...
};

class SubClass : public Base
{
    virtual double Function(int i) const;
    double Function(std::vector<int> vecInts) const;
    double Function(std::map<int> mapInts) const;
};

このデザインに落ち着きがない。仮想関数のオーバーロードを避けるべきであることはわかっていましたが、ここでは少し事情が異なります。

質問> ここに設計上の欠陥はありますか?

ありがとうございました

4

3 に答える 3

8

いいえ、大丈夫です。virtual関数のオーバーロードは問題ありません。仮想機能を非表示にすることは、注意が必要です。

あなたの場合、基本バージョンをオーバーライドし、さらに 2 つのオーバーロードを提供しています。したがって、隠蔽は発生しません。

于 2013-01-18T16:02:22.413 に答える
3

これは設計上の欠陥ではありません。それは完全に問題ありません。

  • 動的ディスパッチを使用しない限り、派生クラスの関数は基本クラスの関数を非表示にし、派生クラスの適切なオーバーロード関数が選択されます (以下のサンプル プログラムの最初の 3 つの出力)。
  • 動的ディスパッチの場合、オブジェクトの実際のタイプに応じて、適切なオーバーライドされた関数 (オーバーライドされた関数はint引数として受け取る関数であることに注意してください) が呼び出されます (以下のサンプルの最後の 3 つの出力)。

わかりやすくするために、サンプル プログラムを考えてみましょう。

#include<iostream>
class Base
{
public:
    virtual double Function(int i) const{std::cout<<"\nIn Base int version";}
};

class SubClass : public Base
{
public:
    virtual double Function(int i) const{std::cout<<"\nIn Derived int version";}
    double Function(std::string str) const{std::cout<<"\nIn Derived string version";}
    double Function(double i) const {std::cout<<"\nIn Derived double version";}
};

int main()
{
    SubClass obj;
    obj.Function(10);
    obj.Function(10.1);
    obj.Function("Hello"); 

    Base Bobj;
    Bobj.Function(10.2);

    Base *ptr = new Base;
    ptr->Function(10.5);

    Base *ptr2 = new SubClass; 
    ptr2->Function(10);
    ptr2->Function(10.5);

    delete ptr;
    delete ptr2;
    return 0;
}

出力は次のとおりです。

In Derived int version
In Derived double version
In Derived string version
In Base int version
In Base int version
In Derived int version
In Derived int version

具体的には、最後の 2 つの出力に注目してください。

于 2013-01-18T16:02:21.017 に答える
1

欠陥はありません。有効な C++ の項目 34 から:

純粋仮想関数は、インターフェイスの継承のみを指定します。

単純な (不純な) 仮想関数は、インターフェイスの継承と既定の実装の継承を指定します。

非仮想関数は、インターフェイスの継承と必須実装の継承を指定します。

Function(int i) は非仮想関数ではなく仮想関数であるため、そのデフォルトの実装は基本クラスでオーバーライドされる場合があります。それが非仮想関数である場合、クラス階層で「is-a」関係を確保するために、オーバーライドされない必須の実装になります。

于 2013-01-18T16:07:02.657 に答える