struct Fooo
{
void func() const {}
protected:
void func() {}
};
...
Fooo fooo;
fooo.func();
编译器说,func 不可访问,因为它是受保护的。为什么会这样?我原本以为非 const 版本根本就看不见,而 const 版本会被调用。
我遇到过这种情况,一个类为成员提供了 const 访问权限,同时还具有供内部使用的非 const 版本的函数。另一种情况是创建一个“受保护的可变”基类,其中所有非 const 访问器都声明为受保护的,因此一个类可以从它派生并保持其数据不被公众改变,而另一个派生类通过将 getter 引入公共范围来使其可用,例如Base::getterFunc;
。
class Base
{
int a;
public:
const auto& getA() const { return a; }
protected:
auto& getA() { return a; }
};
class PublicAccess : public Base
{
public:
Base::getA;
};
class KeepProtected : public Base
{
};
一个特定的例子是Vector
和NormalizedVector
源自VectorBase
。NormalizedVector
可以改变其元素,但不能由公众随机改变。
无论如何,例子不是重点,只是想知道这种不可访问性的背后逻辑是什么,当受保护的版本可以简单地看作不存在并选择 const 版本时。
这是你的错误。访问说明符 (
public
,private
,protected
) 实际上不会改变在重载解析中可见或考虑的成员。它们的唯一作用是,如果它们被重载解析命名或选择,则会导致编译错误。您不能使用它们来“隐藏”成员函数,并导致重载解析在不同上下文中表现不同。重载解析在所有上下文中都将以相同的方式工作。您应该为内部使用的函数赋予与外部接口中不同的名称,并且不要依赖于重载解析。
或者换一种说法,给定一个编译的程序,你可以用 替换所有
private
和protected
,public
程序仍然会(除了一些小的例外)和以前一样工作。它们存在只是为了避免犯错误,例如使用不应该在外部使用的成员。