(我相信)我知道基于常量的重载函数:如果当前时刻是 const,则调用 const 方法,否则调用非 const 方法。

示例(也位于 伊迪奥内):

#include <iostream>

struct S
{
  void print() const { std::cout << "const method" <<std::endl };
  void print()       { std::cout << "non-const method" <<std::endl };
};

int main()
{
  S const s1;
  s1.print(); // prints "const method"
  S s2;
  s2.print(); // prints "non-const method"
  return 0;
};

我尝试/尝试在我的代码中使用它,但是当 const 重载方法不具有相同的访问类别。这可能是不好的风格,但这里有一个例子,反映了返回引用以避免复制和使用的想法 const 限制意外的更改:

struct Color;
struct Shape
{
  double area;
};

class Geometry
{
public:
  // everybody can alter the color of the geometry, so 
  // they get a mutable reference
  Color& color() { return m_color; };

  // not everybody can alter the shape of the Geometry, so
  // they get a constant reference to the shape.
  Shape const& shape() const { return m_shape; };

protected:
  // derived classes can alter the shape, so they get 
  // access to the mutable reference to alter the shape.
  Shape & shape() { return m_shape; };

private:
  Shape m_shape;
  Color m_color;
};

我现在面临的问题是我想让编译器接公众, const- 如果其他函数与几何图形混淆,则返回形状函数,例如按其面积对它们进行着色,为此需要访问几何图形的形状:

// this one fails
void colorByArea() {
  for( Geometry g : geometryList )
  { g.color() = colorMap[g.shape().area]; }
}

// this one is a clunky workaround
void colorByArea() {
  for( Geometry g : geometryList )
  { 
    Geometry const& g_const = g;
    g.color() = colorMap[g_const.shape().area];
  }
}

此操作(或类似操作)失败,并出现以下可以理解的错误:

‘Shape& Geometry::shape()’ is protected 
  Shape & shape() { return m_shape; };

^ error: within this context
  g.color() = colorMap[g.shape().area];

(我在以下位置提出了一个稍微简化的非编译示例 伊迪奥内.)

我(在某种程度上)明白为什么会发生这种情况:g 不是 const 因此,据说应该调用非常量 shape()(即protectec)——但这显然失败了。

所以我猜我的 问题 是:如果无法访问非常量函数,是否有办法“回退”到常量函数?

有帮助吗?

解决方案

如果无法访问非常量函数,是否有办法“回退”到常量函数?

不;重载决策发生在访问检查之前。

这不仅是一种糟糕的风格,而且是一种错误的行为。这是糟糕的设计。公共 getter 函数是 概念上不同 来自受保护的函数,该函数允许具有内部知识的代码修改对象的内部状态。一般来说,这两个函数甚至不需要有相关的返回类型。因此他们不应该有相同的名字。

其他提示

您可以使用 const_cast 允许将 const 版本调用为:

int main()
{
  S s2;
  const_cast<const S&>(s2).print(); // prints "const method"
  return 0;
};

但重命名其中一种方法会更好/更简单。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top