3

私の C++ アプリケーションには、次のようなインターフェイスがあります。

class ICalculator
   {
   public:
      virtual double calculateValue(double d) = 0;
   };

次のようなこのインターフェイスの実装があります。

class MySpecificCalculator
   {
   public:
      virtual double calculateValue(double d);
   };

今、私の同僚はこれについて不平を言い、calculateValue メソッドを保護したほうがよいと私に言いました。そうすれば、呼び出し元が直接の実装ではなく、常にインターフェイスを介して渡されることを保証できます。

これは正しい観察ですか?インターフェイスの実装を保護する方が本当に良いのでしょうか? それとも非公開にすることすらできないのですか?

4

2 に答える 2

10

あなたの同僚は正しいです。

仮想関数を公開しないでください。

ガイドライン #1: テンプレート メソッドを使用して、インターフェイスを非仮想にすることをお勧めします。

ガイドライン #2: 仮想機能を非公開にすることを優先します。

ガイドライン #3: 派生クラスが仮想関数の基本実装を呼び出す必要がある場合にのみ、仮想関数を保護します。

デストラクタの特殊なケースのみ:

ガイドライン #4: 基本クラスのデストラクタは、パブリックで仮想、または保護された非仮想のいずれかである必要があります。

于 2010-11-10T08:40:07.343 に答える
0

あなたの同僚は次のことを意味しているようです:

class ICalculator
{
public:
    virtual double calculateValue(double d) const = 0;
};

class MySpecificCalculator : public ICalculator
{
protected:
    double calculateValue(double d) const;
};

void Calc(double d, const ICalculator& c)
{
    std::cout << "Result = " << c.calculateValue(d) << std::endl;
}

int main ()
{
    MySpecificCalculator c;
    c.calculateValue(2.1);  // dont do this
    Calc(2.1, c);  // do this instead
    return 0;
}

このデザインの利点は見当たりません。具体的な参照から計算を呼び出せないのはなぜですか。派生クラスで calculateValue を protected に移動するには、基本クラスの契約を破ります。MySpecificCalculator を使用して Value を計算することはできませんが、その基本クラスはそう言っています。

ところで、この動作は Chubsdad によって説明された NVI イディオムによってモデル化されていません (これは「正しい」方法です)。

于 2010-11-10T10:23:39.863 に答える