39

クラスを適応可能にし、外部からさまざまなアルゴリズムを選択できるようにしたい場合、C++ での最適な実装は何ですか?

主に2つの可能性があります。

  • 抽象基本クラスを使用し、具体的なオブジェクトを渡します
  • テンプレートを使用する

以下は、さまざまなバージョンで実装された小さな例です。

バージョン 1:抽象基本クラス

class Brake {
public: virtual void stopCar() = 0;  
};

class BrakeWithABS : public Brake {
public: void stopCar() { ... }
};

class Car {
  Brake* _brake;
public:
  Car(Brake* brake) : _brake(brake) { brake->stopCar(); }
};

バージョン 2a:テンプレート

template<class Brake>
class Car {
  Brake brake;
public:
  Car(){ brake.stopCar(); }
};

バージョン 2b:テンプレートとプライベート継承

template<class Brake>
class Car : private Brake {
  using Brake::stopCar;
public:
  Car(){ stopCar(); }
};

Java 出身の私は当然、常にバージョン 1 を使用する傾向がありますが、STL コードなどでは、テンプレート バージョンが好まれることが多いようです。それが本当なら、メモリ効率など(継承なし、仮想関数呼び出しなし)のためだけですか?

バージョン 2a と 2b の間に大きな違いはないことを認識しています。 C++ FAQを参照してください。

これらの可能性についてコメントいただけますか?

4

9 に答える 9

32

経験則は次のとおりです。

1) コンパイル時に具象型を選択する場合は、テンプレートを優先します。より安全になり (コンパイル時エラーと実行時エラー)、おそらくより最適化されます。2) 選択が実行時に (つまり、ユーザーのアクションの結果として) 行われる場合、実際には選択の余地はありません - 継承と仮想関数を使用します。

于 2009-03-02T15:10:18.693 に答える
0

個人的には、いくつかの理由から、テンプレートよりもインターフェイスを使用することを常に好みます。

  1. テンプレートのコンパイルとリンクのエラーは不可解な場合があります
  2. テンプレートに基づくコードをデバッグするのは困難です (少なくとも Visual Studio IDE では)。
  3. テンプレートを使用すると、バイナリを大きくすることができます。
  4. テンプレートでは、すべてのコードをヘッダー ファイルに配置する必要があるため、テンプレート クラスの理解が少し難しくなります。
  5. 初心者のプログラマーがテンプレートを維持するのは困難です。

仮想テーブルによって何らかのオーバーヘッドが生じる場合にのみ、テンプレートを使用します。

もちろん、これは私の個人的な意見です。

于 2009-04-10T10:42:38.573 に答える