【问题标题】:Assigning a std::shared_ptr in assignment operators在赋值运算符中分配 std::shared_ptr
【发布时间】:2013-02-17 23:20:56
【问题描述】:

我正在创建自己的自定义过滤器类以用于 boost::filtered_graph。 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 库会抱怨该函数已被删除。

【问题讨论】:

  • 我不知道为什么你需要指针是 const ......你的意思是 std::shared_ptr&lt;const MoveAbility&gt; m_mv_ab 吗?您希望 std::shared_ptr 本身为 const 还是它指向的对象为 const?
  • 您不能对 any const 数据成员进行分配。这并非特定于 shared_ptr

标签: c++ c++11


【解决方案1】:

您的代码似乎没有任何理由将 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&lt;X&gt; 被读取为“(智能)指向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 作为前缀,这会让人感到困惑。

【讨论】:

  • 多么愚蠢的错误;我不敢相信我错过了。感谢您指出。
  • @Brad 一直在发生,不是那么直观
猜你喜欢
  • 1970-01-01
  • 2020-10-24
  • 1970-01-01
  • 2020-10-08
  • 2015-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多