问题描述
我有一个类看起来像这样:
I have a class that looks something like this:
class ClassA
{
public:
float Get(int num) const;
protected:
float& Get(int num);
}
在类外面,我调用Get()函数。
Outside of the class, I call the Get() function.
float foo = classAInstance.Get(i);
我希望这可以调用公共版本,而是Visual Studio错误:
I expect this to call the public version, but instead Visual Studio errors out:
error C2248: 'ClassA::Get' : cannot access protected member declared in class 'ClassA'
当注释掉受保护的重载并删除对它的所有引用时,代码将编译。
When commenting out the protected overload and removing all references to it, the code compiles.
为什么编译器尝试在可访问的成员可用时使用不可访问的成员?是否有一种被接受的方式强制编译器选择正确的重载?
Why does the compiler try to use the inaccessible member when an accessible one is available? Is there an accepted way to force the compiler to choose the correct overload? Is there a reference to the resolution rules for member functions somewhere?
推荐答案
这是真的,重载解析发生在辅助功能检查之前。标准的第13.3节( [over.match]
)说:
It's true, overload resolution takes place before accessibility checks. Section 13.3 of the standard ([over.match]
) says:
通常的解决方法是为公共和受保护的函数提供不同的名称。
The usual fix is to give the public and protected functions different names.
注意,这在有时候很有用,例如:
Note, this is useful sometimes, example:
class Blah
{
const std::string& name_ref;
Blah(const char*) = delete;
public:
Blah(const std::string& name) : name_ref(name) {}
void do_something_with_name_ref() const;
};
std::string s = "Blam";
Blah b(s); // ok
请注意, name_ref
从中读取,所以它是适当的使它 const
。但是, const
引用可以绑定到临时表,并且将 name_ref
绑定到临时表达式将是一个悬挂引用,导致未定义行为在 do_something_with_name_ref()
。
Note that name_ref
will only be read from, so it's appropriate to make it const
. However, const
references can bind to temporaries, and binding name_ref
to a temporary would be a dangling reference, resulting in undefined behavior in do_something_with_name_ref()
.
Blah c("Kablooey!"); // would be undefined behavior
// the constructor overload makes this a compile error
private构造函数重载防止临时 std :: string
被隐式构造和绑定。
The private constructor overload prevents a temporary std::string
from being implicitly constructed and bound.
这篇关于使用const /非const重载分辨率的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!