Como tornar uma classe privada dentro de um espaço de nomes em C++?
Como tornar uma classe privada dentro de um espaço de nomes em C++ e impedir que outros acedam à classe fora do espaço de nomes, por exemplo:
namespace company{
class MyPublicClass{ ... } // This should be accessible
class MyPrivateClass{ ... } // This should NOT be accessible
}
3 answers
Você não pode ter especificadores de Acesso para espaços de nomes, mas você pode para classes:
class company {
// Private (default)
class MyPrivateClass { ... };
public:
class MyPublicClass { ... };
};
Você acede às classes tal como para um espaço de nomes com o operador de escopo:
company::MyPublicClass my_public_object;
Se a classe " pública "deve ter acesso à classe" privada", então a classe" privada" deve ser uma classe "pública".
Existe também outra maneira, que é simplesmente não ter a definição MyPrivateClass
num ficheiro de cabeçalho público. Ou define a classe na fonte ficheiro, ou num ficheiro de cabeçalho privado apenas incluído internamente.
Qual a maneira de escolher depende do seu design e casos de uso.
Os espaços de nomes C++ não fornecem nenhum acessor com escopo, nem as declarações de classes (vs c#, por exemplo).
A forma habitual é introduzir um espaço de nomes internal
para indicar public
que o uso não é pretendido.
Você pode restringir o acesso usando friend
especificadores.
Você também pode usar alguns truques, para tornar mais difícil o acesso a uma interface publicamente como explicado aqui: Como posso remover/remodelar uma declaração de dependência de "amigo" adequadamente?
Pode usar unnamed namespace
. Os nomes que aparecem em um espaço de nomes Sem Nome têm ligação interna, mas os nomes que aparecem em um espaço de nomes nomeado e não têm nenhum especificador de classe de armazenamento, por padrão, têm ligação externa.
source1.cpp
:
//source1.cpp
namespace company{
class MyPublicClass{ ... };
namespace{
class MyPrivateClass{ ... };
}
}
void f1(){
company::MyPrivateClass m;
}
MyPublicClass
tem uma ligação externa e tem uma ligação interna. Então não há problema com source1
e ele pode ser compilado como uma biblioteca, mas se tivermos outro arquivo chamado source2.cpp
:
//source2.cpp
void f2(){
company::MyPrivateClass m;
}
source2
não pode ser. ligado com o compilado source1
e não podemos referir-nos a MyPrivateClass
.