c ++如何为同一成员创建公共和受保护的访问器
Posted
技术标签:
【中文标题】c ++如何为同一成员创建公共和受保护的访问器【英文标题】:c++ how to create public and protected accessors to same member 【发布时间】:2016-09-03 09:02:50 【问题描述】:如果我有两种方法——一种是公共的,一种是保护的,返回对同一成员的引用,我会得到以下编译错误:
'Server::getManager': cannot access protected member declared in class 'Server'
当我注释掉受保护的函数时,代码可以工作。你能告诉我为什么会这样吗?为什么编译器找不到同一成员的公共函数?
class Manager
;
class Server
public:
const Manager & getManager() const return m_man;
protected:
Manager & getManager() return m_man; // <-- after removing this method I get no compilation error
private:
Manager m_man;
;
int main()
Server s;
const Manager& m = s.getManager();
return 0;
【问题讨论】:
编译器找到公共的,但保护的更好。它完全匹配。 如果公共的返回相同的东西,你为什么需要受保护的? 访问说明符在重载决议后评估。所以编译器首先找到最佳匹配,然后然后检查它是否可以访问。我建议您简单地重命名受保护的成员,因为您显然打算在不同的上下文中使用它。 @wizzardmr42,因为类或它的派生类可能想要修改管理器并且是正确的。在这里也使用访问器函数,具有无需修补整个代码库即可更改实现的相同好处。 【参考方案1】:为什么编译器找不到同一成员的公共函数?
这不是问题。编译器找到 both 函数并执行重载决议以确定哪个是最佳可行候选者。两位候选人是:
Manager& getManager() // protected
Manager const& getManager() const // public
对于成员函数,有一个隐式的第一个对象参数,即类本身的实例。在这种情况下,这两个函数变为:
getManager(Server& ) // protected
getManager(Server const& ) // public
我们在一个不是 const
的对象 (s
) 上调用它。两个候选者都是可行的,但 public
候选者比 protected
候选者引用了一个 more cv 限定对象 - 所以它不太受欢迎。标准版在 [over.ics.rank] 中:
标准转换序列S1是比标准转换序列更好的转换序列 S2 如果 — S1 和 S2 是引用绑定(8.5.3),引用所引用的类型相同 *** cv 限定符除外的类型,以及由 S2 初始化的引用所引用的类型 比由 S1 初始化的引用所引用的类型更具有 cv 限定。
因此,protected
候选者是首选 - 所以这就是被调用的那个。
不幸的是,它是protected
,所以称它为格式不正确。在重载解决之后检查访问控制。所以你必须以某种方式重组你的程序。您可以简单地将s
转换为const
:
const Manager& m = const_cast<Server const&>(s).getManager();
这将使protected
候选人不可行。
【讨论】:
或者调用受保护的getWritableManager。你没有有重载函数。以上是关于c ++如何为同一成员创建公共和受保护的访问器的主要内容,如果未能解决你的问题,请参考以下文章