让我们考虑一下这段代码:
struct message
{
uint8_t* data;
size_t length;
};
class device_base
{
// ...
public:
virtual ssize_t exec(uint8_t cmd, const uint8_t* data = nullptr, size_t length = 0);
inline ssize_t exec(uint8_t cmd, const message& msg)
{
return exec(cmd, msg.data, msg.length);
}
// ...
};
class device : public device_base
{
// The exec method do not overloaded or overridden here.
};
class device_uart : public device
{
// ...
public:
ssize_t exec(uint8_t cmd, const uint8_t* data = nullptr, size_t length = 0);
void some_method(const message&);
// ...
};
// ...
void device_uart::some_method(const message& msg)
{
// exec(SOME_COMMAND, msg); // The inline method device_base::exec is invisible here by some reason.
device::exec(SOME_COMMAND, msg); // OK.
device_base::exec(SOME_COMMAND, msg); // OK too.
exec(SOME_COMMAND, msg.data, msg.length); // OK, of course.
}
为什么在device_uart
类中看不到内联非虚拟方法exec
?
最佳答案
Why the inline non-virtual method
exec
is not seen in thedevice_uart
class?
这是一种“隐名”;在类 device_uart
的成员函数中, device_base::exec
被隐藏,因为有一个同名的方法 exec
在类里面device_uart
本身。函数不能通过不同作用域重载。
根据unqualified name lookup的规则:
name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined.
这意味着名字 exec
将在 device_uart
范围内找到,然后名称查找停止,基类中的名称根本不会被考虑用于重载解析。
要解决这个问题,您可以使用作用域解析运算符::使其成为qualified name lookup正如你所展示的;或者
您可以使用using
要将名称引入同一范围,重载决策将按预期生效。例如
class device_uart : public device
{
// ...
using device_base::exec; // introduce the names from base class into the same scope
public:
// ...
};
关于c++ - 为什么如果没有显式范围解析,父类的父方法就无法访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41776297/