Почему метод parent родительских классов не доступен без явного разрешения области?

Давайте рассмотрим этот код:

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.
}

Почему встроенный не виртуальный метод exec не видно в device_uart учебный класс?

2

Решение

Почему встроенный не виртуальный метод exec не видно в device_uart учебный класс?

Это своего рода «сокрытие имени»; в функции-члена класса device_uart, device_base::exec скрыт, потому что есть метод с тем же именем exec в классе device_uart сам. Функции не могут быть перегружены через разные области видимости.

Согласно правилу поиск безусловного имени:

поиск имени исследует области как описано ниже, пока это не находит в
по крайней мере одно объявление любого вида, когда поиск останавливается и
дальнейшие области не рассматриваются.

Это означает, что имя exec будет найден в объеме device_uart, тогда поиск имен останавливается, имена в базовом классе вообще не будут рассматриваться для разрешения перегрузки.

Чтобы решить эту проблему, вы можете использовать оператор разрешения области :: чтобы сделать это поиск подходящего имени как вы показали; или же
ты можешь использовать using чтобы ввести имена в одну и ту же область, разрешение перегрузки будет действовать, как и ожидалось. например

class device_uart : public device
{
// ...
using device_base::exec; // introduce the names from base class into the same scope
public:
// ...
};
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]