我目前正在编写一些代码,我有自定义句柄类型。有问题的代码与此非常相似:
struct SegmentData
{
//...
};
class SegmentHandle
{
public:
SegmentHandle(Path * _path, int _idx);
void setPosition(float _x, float _y);
float positionX() const;
float positionY() const;
private:
Path * m_path;
int m_index;
};
class Path
{
public:
SegmentHandle segmentHandle(int _idx) const
{
// Path object itself can never be const so this should be fine
return SegmentHandle(const_cast<Path*>(this), _idx);
}
private:
std::vector<SegmentData> m_segmentData;
};
Path * path = createPath();
//...add some segments
SegmentHandle seg = path.segmentHandle(3);
seg.setPosition(100, 30);
//...
就const的正确性而言,这并不是很好,因为我们可以通过Path
修改SegmentHandle
数据,尽管getter是const。要解决此问题,我尝试为const
和非const
句柄设置单独的类型(类似于标准库中的const_iterator
vs iterator
),即:
template<class PT>
class SegmentHandleT
{
public:
SegmentHandleT(PT * _path, int _idx);
void setPosition(float _x, float _y);
float positionX() const;
float positionY() const;
private:
PT * m_path;
int m_index;
};
using SegmentHandle = SegmentHandleT<Path>;
using ConstSegmentHandle = SegmentHandleT<const Path>;
虽然在这样的简单示例中看起来很好,但在现实世界的代码库中,您有多个交互式句柄类型,它会显着地破坏代码复杂性,引入模板,否则它们将不会被使用/需要等等。 这严重诱使我坚持使用选项1,因为从技术上讲,该函数不直接修改底层路径对象。在这样的场景中,还有其他选择来维持更高级别的 const正确性,在这种情况下,代码复杂性和实际世界增益之间的权衡更加平衡吗?
谢谢!