在C++中使用非常量引用作为常量

Using non-const reference as const in C++

本文关键字:常量 引用 非常 C++      更新时间:2023-10-16

我试图在代码中正确使用const关键字。我有一个类a,其中有一些其他类Bstd::array作为成员变量。

我有一个访问器来获取AB成员之一。

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重载了更多的方法。这个改动在我看来一团糟。我想我错过了一种更干净的方法来实现我的目标(使用常量a&作为序列化程序参数(。

我只使用常量A实例返回的非常常量B引用的常量成员。我应该在这里重构什么,以获得遵循c++良好实践的干净代码?

我只使用常量A实例返回的非常量B实例引用的常量成员。我应该在这里重构什么,以获得遵循c++良好实践的干净代码?

干净的idomatic方式是你不想要的,因为你认为它很乱。你的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的方法。只有当你需要它们时,nonconst才会提供第二次过载(而不是相反(。在更多的情况下,您的代码会遇到同样的问题。举个例子,operator<<的重载应该具有以下签名:

std::ostream& operator<<(std::ostream&, const A&); 
// ^--------  const !!!

最后但同样重要的是:我想这是由于您的示例的简化,但您的getA看起来像是封装的尝试。事实并非如此。一旦返回了对成员的非常数引用,就可以将该成员设为publicgetB的唯一用途是可以编写a.getB(index)而不是a.m_bCollection[index],但它没有实现封装。