如何删除类似的 const 和非常量成员函数之间的代码重复?

新手上路,请多包涵

假设我有以下 class X 我想在其中返回对内部成员的访问权限:

 class Z
{
    // details
};

class X
{
    std::vector<Z> vecZ;

public:
    Z& Z(size_t index)
    {
        // massive amounts of code for validating index

        Z& ret = vecZ[index];

        // even more code for determining that the Z instance
        // at index is *exactly* the right sort of Z (a process
        // which involves calculating leap years in which
        // religious holidays fall on Tuesdays for
        // the next thousand years or so)

        return ret;
    }
    const Z& Z(size_t index) const
    {
        // identical to non-const X::Z(), except printed in
        // a lighter shade of gray since
        // we're running low on toner by this point
    }
};

两个成员函数 X::Z()X::Z() const 在大括号内具有相同的代码。这是重复的代码 ,可能会导致逻辑复杂的长函数出现维护问题

有没有办法避免这种代码重复?

原文由 Kevin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 540
2 个回答

是的,可以避免代码重复。您需要使用 const 成员函数来拥有逻辑并让非常量成员函数调用 const 成员函数并将返回值重新转换为非常量引用(如果函数返回指针,则为指针):

 class X
{
   std::vector<Z> vecZ;

public:
   const Z& z(size_t index) const
   {
      // same really-really-really long access
      // and checking code as in OP
      // ...
      return vecZ[index];
   }

   Z& z(size_t index)
   {
      // One line. One ugly, ugly line - but just one line!
      return const_cast<Z&>( static_cast<const X&>(*this).z(index) );
   }

 #if 0 // A slightly less-ugly version
   Z& Z(size_t index)
   {
      // Two lines -- one cast. This is slightly less ugly but takes an extra line.
      const X& constMe = *this;
      return const_cast<Z&>( constMe.z(index) );
   }
 #endif
};

注意: 重要的是 不要 将逻辑放在非常量函数中并且让常量函数调用非常量函数 - 这可能会导致未定义的行为。原因是常量类实例被强制转换为非常量实例。非常量成员函数可能会意外修改类,C++ 标准规定这将导致未定义的行为。

原文由 Kevin 发布,翻译遵循 CC BY-SA 4.0 许可协议

由于 推断出,C++23 更新了这个问题的最佳答案:

 struct s {
    auto && f(this auto && self) {
        // all the common code goes here
    }
};

单个函数模板可作为普通成员函数调用,并为您推导出正确的引用类型。没有错误的转换,没有为概念上一件事的东西编写多个函数。

原文由 David Stone 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题