struct Fooo
{
void func() const {}
protected:
void func() {}
};
...
Fooo fooo;
fooo.func();
O compilador diz que func é inacessÃvel, porque é protegido. Por que funciona assim? Eu esperava que a versão não-const simplesmente não fosse vista e a const fosse chamada.
Eu encontrei isso com uma classe dando acesso const ao membro enquanto também tinha a versão não const da função para uso interno. O outro caso ao fazer uma classe base "protected mutable" com todos os acessadores não const declarados protected, então uma classe poderia derivar dela e manter seus dados não mutáveis ​​pelo público e outra classe derivada tornou os getters disponÃveis ao trazer para o escopo público, como Base::getterFunc;
.
class Base
{
int a;
public:
const auto& getA() const { return a; }
protected:
auto& getA() { return a; }
};
class PublicAccess : public Base
{
public:
Base::getA;
};
class KeepProtected : public Base
{
};
Um caso especÃfico foi Vector
e NormalizedVector
derivado de VectorBase
. NormalizedVector
pode mutar seus elementos não aleatoriamente pelo público.
Em qualquer caso, os exemplos não são o ponto, apenas me pergunto qual é a lógica por trás dessa inacessibilidade, quando a versão protegida poderia ser simplesmente vista como inexistente e a versão const poderia ser escolhida.
Esse é seu erro. Os especificadores de acesso (
public
,private
,protected
) de fato não mudam quais membros são vistos ou considerados para resolução de sobrecarga.O único efeito que eles têm é causar um erro de compilação se forem nomeados ou escolhidos pela resolução de sobrecarga. Você não pode usá-los para "esconder" funções de membro e fazer com que a resolução de sobrecarga se comporte de forma diferente em contextos diferentes. A resolução de sobrecarga funcionará da mesma forma em todos os contextos. Você deve dar às funções para uso interno nomes diferentes daqueles na interface externa e não depender da resolução de sobrecarga.
Ou para dizer de forma um pouco diferente, dado um programa que compila, você poderia substituir todos os
private
andprotected
porpublic
e o programa (com algumas pequenas exceções) ainda funcionaria exatamente da mesma forma que antes. Eles existem apenas para evitar erros, por exemplo, usando um membro que não deveria ser usado externamente.