首页 > 解决方案 > 在 C++ 中使用非常量引用作为 const

问题描述

我正在尝试在我的代码中正确使用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 重载了更多方法。这种修改对我来说似乎是一团糟。我想我错过了一种更简洁的方式来实现我的目标(使用const A&作为序列化程序参数)。

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

标签: c++constants

解决方案


我只使用由 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]但它不能实现封装。


推荐阅读