c++ - 在 C++ 中使用非常量引用作为 const
问题描述
我正在尝试在我的代码中正确使用const关键字。我有一个A类,其中有一些其他类B和std::array作为成员变量。
我有一个访问器来获取A的B成员之一。
class B
{
public:
int getMember() const;
};
class A
{
public:
B& getB(const size_t idx)
{
return m_bCollection[idx];
}
private:
std::array<B, 10> m_bCollection;
};
然后我添加了一个函数来为 yaml-cpp 序列化一个 A 的实例
YAML::Emitter& operator<<(YAML::Emitter& out, const A& a)
{
// some stuff here, and then:
out << a.getB(1).getMember();
return out;
}
这不会编译,因为对getB的调用违反了我的序列化函数参数的const修饰符。
错误:将“const A”作为“this”参数传递会丢弃限定符
我可以重载我的getB方法以获得它的恒定版本,但这似乎不是很干净......
B& A::getB(const size_t idx);
const B& A::getB(const size_t idx) const;
我在其他类似的类上也有这个问题,并且 const 重载了更多方法。这种修改对我来说似乎是一团糟。我想我错过了一种更简洁的方式来实现我的目标(使用const A&作为序列化程序参数)。
我只使用由 const A实例返回的非 const B实例引用的const 成员。我应该在这里重构什么以获得遵循 c++ 良好实践的干净代码?
解决方案
我只使用由 const A 实例返回的非 const B 实例引用的 const 成员。我应该在这里重构什么以获得遵循 c++ 良好实践的干净代码?
干净的惯用方式是您不想要的方式,因为您认为它很混乱。你A
应该看起来像这样
class A
{
public:
B& getB(size_t idx)
{
return m_bCollection[idx];
}
const B& getB(size_t idx) const {
return m_bCollection[idx];
}
private:
std::array<B, 10> m_bCollection;
};
为避免代码重复,您可以使用此处提供的解决方案或该问题的其他答案。
const
通常,您应该创建默认不修改成员的方法。仅当您需要它们时,非 const 才提供第二个重载(而不是相反)。在更多情况下,您的代码会碰壁。举个例子,for 的重载operator<<
应该有这个签名:
std::ostream& operator<<(std::ostream&, const A&);
// ^-------- const !!!
最后但并非最不重要的一点:我想这是由于您的示例的简化,但您getA
看起来像是封装的尝试。事实上并非如此。一旦您返回了对成员的非常量引用,您也可以创建该成员public
。唯一的目的getB
是你可以写a.getB(index)
而不是,a.m_bCollection[index]
但它不能实现封装。
推荐阅读
- r - RGraphviz 哈斯图仅显示一个标签
- python-3.x - python 3.8.7 不再向后兼容 python 3.4 了吗?
- go - go mod tidy 复制导入本地包的路径,go.mod 替换为“./b”,但模块路径为 github.com/x/y/src/a/b/src/a/b/go.mod
- elasticsearch - ES查询一个字段是否存在,或者另一个字段是否有某个值
- osmnx - 我无法从地点信息中检索足迹
- javascript - 如何让 TradingView 图表显示所有点而无需滚动?
- macos - M1 Macbook pro 可以与 Lampps 兼容吗?
- python - 将 Python 对象转换为兼容的类型注解
- php - 如何按字母顺序按 PHP 中任何特定键的值对二维数组进行排序?
- python - flask wtforms 根据选择字段动态显示表单字段