0

Item一意であると想定されているため、コピーできない s を含むゲームがあります。

class Item {
  Item() noexcept;
  Item(Item&&) noexcept;
  Item(Item const&) = delete;
// ...
};

class Creatureを受け取り、Itemそれを自分の に追加することができinventoryます:

void Creature::receive_item(Item&& item) noexcept {
  this->inventory.push_back(std::move(item));
}

void caller_code() {
  Creature creature;
  Item item;
  // ...
  creature.receive_item(std::move(item));
}

このアプローチは素晴らしくきれいに見えますが、小さな問題があります。コードの一部が後で回復でき、 'sstd::bad_allocによってスローされたものをキャッチした場合、ゲーム内のロジックは未定義です。失われるだけです。さらに、この可能性のためだけに指定子を削除する必要があります。recieve_item()push_back()Itemnoexcept

したがって、この方法で例外の安全性を提供できます (間違っている場合は指摘してください)。

void Creature::receive_item(Item& item) {
  this->inventory.resize(this->inventory.size() + 1);
  // if it needs to allocate and fails, throws leaving the item untouched
  this->inventory.back() = std::move(item);
}

void caller_code() {
  Creature creature;
  Item item;
  // ...
  creature.receive_item(item); // no moving
}

ただし、現在、新しい欠点があります。

  • std::move()呼び出し元のコードに がないため、 item;を移動したという事実がわかりにくくなります。
  • 「resize(+1)」の部分は見苦しく、コード レビュー中に誤解される可能性があります。

質問はタイトルにあります。このような奇妙なケースでも例外の安全性は良い設計と見なされますか?

4

1 に答える 1