我正在创建自己的自定义Filter类,以便在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库会抱怨该函数被删除。
答案 0 :(得分:11)
您的代码似乎没有任何理由将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>
被读取“(智能)指针指向X”:< / p>
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
作为前缀,这会让人感到困惑。