跨公共/受保护访问的基于const的函数重载
const-based function overloading accross public/protected access
(我相信)我知道基于const重载函数:如果instant是const,则调用const方法,否则调用非常量方法。
示例(也在ideone):
#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];
(我在ideone上举了一个稍微简化的非编译示例。)
我(在一定程度上)理解了为什么会发生这种情况:g
不是const
,因此应该调用protectec的non-const shape(),但这显然失败了。
所以我想我的问题是:如果一个非常量函数不可访问,有没有一种方法可以让常量函数"回退">
如果一个非常量函数不可访问,是否有一种方法可以对常量函数进行某种"回退">
否;过载解决发生在访问检查之前。
这不仅仅是糟糕的风格;这是糟糕的设计。公共getter函数在概念上与受保护函数不同,后者允许了解内部信息的代码修改对象的内部状态。通常,这两个函数甚至不需要具有相关的返回类型。因此,它们不应该有相同的名称。
您可以使用const_cast
来允许将const版本调用为:
int main()
{
S s2;
const_cast<const S&>(s2).print(); // prints "const method"
return 0;
};
但是重命名其中一个方法会更好/更简单。
相关文章:
- 为什么使用SFINAE而不是函数重载
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- c++:可变模板和函数重载
- 在缺少函数重载时抛出异常,并带有 std::variant 而不是编译时错误
- 解决模板成员函数重载
- 为什么不允许成员函数和非成员函数之间的函数重载?
- 推断模板化函数中的函数重载
- C++复制函数重载导致"must be a nonstatic member function"错误
- 为什么 std::sort 找不到合适的(静态成员)函数重载?
- 可变参数泛型 lambda 和函数重载
- C++中的函数重载和继承
- 当有右值构造函数可用时,为什么从右值调用类引用构造函数重载?
- C/C++ 可变参数宏函数重载
- 将基类的成员函数重载到其他派生类C++
- C++ 函数重载匹配
- C++函数重载,具体步骤是什么
- C++:使用 param pack 显式调用函数重载
- 隐式生成的函数重载用于右值参数?
- 使用函数重载输入运算符
- 运算符重载函数上的函数重载