3

このコードは、Objective-C での動的バインディングの古典的な例です [1] :

float total = tareWeight;     // start with weight of empty container
int i, n = [self size];       // n = number of members
for (i = 0; i < n; ++i) {     // loop over each member
    id member = [self at:i];  // get next member
    total += [member weight]; // accumulate weight of contents
}
return total;                 // return total weight to caller

この言語の経験があり、C++ で最初のステップを実行するプログラマーとして、私は知りたいです: C++ では、ある種の遅延バインディングもサポートされているため、これをどのように実装するのでしょうか?

この例では、各メンバーは任意のクラスに属することができると想定していますがweight、もちろんメソッドの実装は必須です。最近では、プロトコルなどのメカニズムを使用して、実装に互換性を持たせることもできますが (その後、 として宣言memberします id<Matter>)、機能するためにはまったく必要ありません。

C++ では、いわゆる仮想関数を使用してスーパー クラスを作成することが唯一の選択肢でしょうか?

編集

明確にするために、上記のコードは、コンポーネントの合計重量を返すコンテナ クラス メソッドと見なすことができます。コンテナに何が入るかは事前にはわかりません。それは任意のオブジェクトである可能性があります。これらのオブジェクトがメッセージに応答することだけがわかりますweight


[1]オブジェクト指向プログラミング、進化的アプローチ、第 2 版、1991 年- ブラッド J. コックス、アンドリュー J. ノボビルスキー - 第 4 章 65 ページ

4

2 に答える 2

1

C++ で実際に最も近いものは、仮想関数を持つスーパー クラスです。あなたの例ではそれが必要かどうかは明らかではありませんが、レイトバインディングを本当に気にするなら仮想関数。Weight は、スーパー クラスでパブリックにアクセス可能なデータ メンバーである可能性があります。

C++ での動的バインディングの形式は、厳密にクラス階層の上下にあります。これにより、コンパイラはすべてをランタイム システムに任せるのではなく、特定のレベルのチェックを行うことができます。安全でないキャストを使用しない限り。

C++ では多重継承が行われることに注意してください。したがって、使用できるようにするクラスは、このスーパークラスから継承する必要があるだけでなく、まったく関係のない他のクラスからも継承できます。

于 2012-03-29T14:47:18.150 に答える
1

weighableメンバー変数は、基本クラスへのポインターである必要があります。このようなポインターは、任意の派生インスタンスを参照できます。

ポインタはメモリ リークのリスクをもたらすため、スマート ポインタにするのが賢明です。C++11 にはunique_ptr. あなたのクラスは次のようになります

class heavyContainer {
  std::vector<std::unique_ptr<weighable>> members;
 public:
  float total_weight() {
    float result = tareWeight;
    for(auto& member: members)
      result += member->weight();
    return result;
  }
  ...
};

の任意の派生インスタンスでメンバーを初期化するにはweighable、これらのオブジェクトをヒープ割り当てする必要があります。基本クラスのポインターによって参照されるオブジェクトをコピーする一般的な方法がないため、これは少し注意が必要です。1 つの方法は、挿入関数をテンプレートにすることです。

template<class WeighableDerivedObject>
heavyContainer::insert(const WeighableDerivedObject& obj){
  members.push_back(new WeighableDerivedObject(obj));
}

これは、C++11 の移動セマンティクスを使用して、もう少し効率的にすることができます。

于 2012-03-29T14:55:54.137 に答える