C ++, как создать открытые и защищенные средства доступа для одного и того же члена

Если у меня есть два метода — один общедоступный, другой защищенный, который возвращает ссылку на один и тот же член, я получаю следующую ошибку компиляции:

'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;
}

6

Решение

Почему компилятор не может найти открытую функцию для того же члена?

Это не проблема. Компилятор находит и то и другое функции и выполняет разрешение перегрузки, чтобы определить, какой из них является наиболее подходящим кандидатом. Два кандидата:

Manager&       getManager()        // protected
Manager const& getManager() const  // public

Для функций-членов существует неявный параметр первого объекта, который является экземпляром самого класса. В этом случае две функции становятся:

getManager(Server& )         // protected
getManager(Server const& )   // public

Мы вызываем его на объекте (s) это не const, Оба кандидата жизнеспособны, но public кандидат берет ссылку на Больше резюме-квалифицированный объект, чем protected кандидат — так что это менее предпочтительно. Стандарт находится в [over.ics.rank]:

Стандартная последовательность преобразования S1 является лучшей последовательностью преобразования, чем стандартная последовательность преобразования
S2 если
— S1 и S2 являются привязками ссылок (8.5.3), и типы, на которые ссылаются ссылки, одинаковы
type за исключением cv-квалификаторов верхнего уровня и типа, к которому относится ссылка, инициализированная S2
является более квалифицированным по cv, чем тип, к которому относится ссылка, инициализированная S1.

В результате protected Кандидат является предпочтительным, так что это тот, который называется.

К сожалению это protectedтак что называть это плохо сформировано. Контроль доступа проверяется после разрешения перегрузки. Так что вам придется как-то реструктурировать свою программу. Вы могли бы просто бросить s в const:

const Manager& m = const_cast<Server const&>(s).getManager();

Это сделало бы protected кандидат нежизнеспособный.

6

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

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

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