5

boost::filtered_graph で使用する独自のカスタム Filter クラスを作成しています。WeightMap の概念には、既定のコンストラクター、コピー コンストラクター、および代入演算子が必要です。

std::shared_ptr プライベート メンバーを持つ以下のクラスを作成しました。私の質問は、代入演算子をどのように書くべきかということです。コピー コンストラクターは問題ありませんでしたが、代入演算子は機能しません。

class BFDMFilter
{
private:
const BGraph* m_battlemap;
const std::shared_ptr<MoveAbility> m_mv_ab;

public:
BFDMFilter() : m_battlemap(nullptr), m_mv_ab() { }
BFDMFilter(const BGraph* bmap, std::shared_ptr<MoveAbility> mv) : m_battlemap(bmap), m_mv_ab(mv) { }

BFDMFilter(const BFDMFilter& filter) : m_battlemap(filter.m_battlemap), m_mv_ab(filter.m_mv_ab) { }
BFDMFilter& operator=(const BFDMFilter& filter) 
{
  if(this != &filter)
  {
m_battlemap = filter.m_battlemap;
m_mv_ab = filter.m_mv_ab;
  }

  return *this;
}

bool operator()(const Edge& edge) const 
{ 
  Tile::TileEdge path = (*m_battlemap)[edge];

  return m_mv_ab->CanMove(path.TerrainType()) > 0.0;
}

bool operator()(const Vertex& vertex) const 
{ 
  Tile tile = (*m_battlemap)[vertex];

  return m_mv_ab->CanMove(tile.TerrainType()) > 0.0;
}
};

次に、コンパイルエラーが発生します。

error: passing ‘const std::shared_ptr<momme::battle::MoveAbility>’ as ‘this’ argument of ‘std::shared_ptr<_Tp>& std::shared_ptr<_Tp>::operator=(std::shared_ptr<_Tp>&&) [with _Tp = momme::battle::MoveAbility, std::shared_ptr<_Tp> = std::shared_ptr<momme::battle::MoveAbility>]’ discards qualifiers [-fpermissive]

理由はわかります。割り当て演算子は、割り当てを行うときに shared_ptr の参照カウントを変更して、開いている参照の数を追跡できるようにします。しかし、代入演算子はどのように書けばよいのでしょうか? std::weak_ptr にも同じ動作があり、参照を非 const にすると、boost ライブラリは関数が削除されたと文句を言います。

4

1 に答える 1

12

コードから次のように宣言する理由はないようm_mv_abです

const std::shared_ptr<MoveAbility> m_mv_ab;

これは、次のスマート ポインター バージョンです。

MoveAbility * const m_mv_ab;

(非定数への定数ポインタMoveAbility)

MoveAbilityポイント先のオブジェクトを変更せずに にしたい場合は、次のようconstにする必要があります。

std::shared_ptr<const MoveAbility> m_mv_ab;

これは、次のスマート ポインター バージョンです。

const MoveAbility * m_mv_ab;

(定数への非定数ポインターMoveAbility)

これをもう少し直感的にするためconstに、接尾辞として常に右から左にstd::shared_ptr<X>読むことができます。

std::shared_ptr<MoveAbility> const m_mv_ab; // const ptr to non-const MoveAbility
MoveAbility * const m_mv_ab; // const ptr to non-const MoveAbility

std::shared_ptr<MoveAbility const> m_mv_ab; // non-const ptr to const MoveAbility
MoveAbility const * m_mv_ab; // non-const ptr to const MoveAbility

しかし、ほとんどの人はconst可能な限り接頭辞として使用するため、混乱を招きます。

于 2013-03-03T23:00:05.993 に答える