A resposta para por que colocamos variáveis de membro privadas nos cabeçalhos de C ++ é que o tamanho da classe deve ser conhecido nos pontos em que as instâncias são declaradas, para que o compilador possa gerar código que se mova adequadamente sobre a pilha.
Por que precisamos colocar membros privados em cabeçalhos?
Mas existe algum motivo para declarar funções privadas na definição de classe?
A alternativa seria essencialmente o idioma pimpl, mas sem a indireção supérflua.
Esse recurso de idioma é mais do que um erro histórico?
Se você permitisse que métodos fossem adicionados a uma classe fora de sua definição, eles poderiam ser adicionados em qualquer lugar , em qualquer arquivo, por qualquer pessoa.
Isso daria imediatamente a todo código do cliente acesso trivial a membros de dados privados e protegidos.
Depois de terminar a definição da classe, não há como marcar alguns arquivos como sendo especialmente abençoados pelo autor para estendê-lo - existem apenas unidades de tradução simples. Portanto, a única maneira razoável de dizer ao compilador que um conjunto específico de métodos é oficial ou abençoado pelo autor da classe é declará-los dentro da classe.
Observe que temos acesso direto à memória em C ++, o que significa que geralmente é trivial criar um tipo de sombra com o mesmo layout de memória da sua classe, adicionar meus próprios métodos (ou apenas tornar todos os dados públicos) e
reinterpret_cast
. Ou posso encontrar o código da sua função privada ou desmontá-lo. Ou procure o endereço da função na tabela de símbolos e ligue ou diretamente.Esses especificadores de acesso não tentam impedir esses ataques, porque isso não é possível. Eles indicam apenas como uma classe deve ser usada.
fonte
A resposta aceita explica isso para funções privadas virtuais , mas isso apenas responde a uma faceta específica da pergunta, que é consideravelmente mais limitada do que o que o OP pediu. Portanto, precisamos reformular: Por que somos obrigados a declarar funções privadas não virtuais nos cabeçalhos?
Outra resposta invoca o fato de que as classes devem ser declaradas em um bloco - após o qual são seladas e não podem ser adicionadas. Isso é o que você faria ao omitir a declaração de um método privado no cabeçalho e tentar defini-lo em outro lugar. Bom ponto. Por que alguns usuários da classe podem aumentá-lo de uma maneira que outros usuários não podem observar? Métodos particulares fazem parte e não são excluídos disso. Mas então você pergunta por que eles estão incluídos, e parece um pouco tautológico. Por que os usuários da classe precisam saber sobre eles? Se eles não estavam visíveis, os usuários não poderiam adicionar nenhum, e ei presto.
Então, eu queria fornecer uma resposta que, em vez de incluir métodos privados por padrão, forneça pontos específicos em favor de torná-los visíveis para os usuários. Um motivo mecanicista para funções privadas não virtuais que requerem declaração pública é apresentado no GotW # 100 de Herb Sutter sobre o idioma Pimpl como parte de sua lógica. Não vou falar sobre o Pimpl aqui, pois tenho certeza de que todos sabemos disso. Mas aqui está a parte relevante:
Sutter é, é claro, uma fonte extremamente confiável como membro do Comitê, então ele conhece "uma decisão deliberada de projeto" quando vê uma. E a idéia de exigir declaração pública de métodos privados como uma maneira de evitar a semântica alterada ou a acessibilidade acidentalmente interrompida posteriormente é provavelmente a lógica mais convincente. Felizmente, como a coisa toda parecia bastante inútil antes de agora!
fonte
Há duas razões para fazer isso.
Primeiro, perceba que o especificador de acesso é para o compilador e não é relevante no tempo de execução. Acessar um membro privado fora do escopo é um erro de compilação .
Concisão
Considere uma função curta, uma ou duas linhas. Existe para reduzir a replicação de código em outro lugar, o que também tem a vantagem de poder alterar a maneira como um algoritmo ou qualquer outra coisa funciona em um local, em vez de muitos (por exemplo, alterar um algoritmo de classificação).
Você prefere ter uma ou duas linhas rápidas no cabeçalho ou ter o protótipo de função lá mais uma implementação em algum lugar? É mais fácil encontrar no cabeçalho e, para funções curtas, é muito mais detalhado ter uma implementação separada.
Há outra grande vantagem, que é ...
Funções em linha
Uma função privada pode ser incorporada e isso necessariamente exige que ela esteja no cabeçalho. Considere isto:
A função privada pode ser incorporada juntamente com a função pública. Isso é feito a critério do compilador, pois a
inline
palavra-chave é tecnicamente uma sugestão , não um requisito.fonte
inline
, não há motivo para usar a palavra-chave lá..cpp
membro no arquivo, destacada por funções-membro definidas fora da definição de classe, mas essa função não seria privada.Outro motivo para ter métodos particulares no arquivo de cabeçalho: Há casos em que um método público interno não passa de uma chamada de um ou vários métodos particulares. Ter os métodos privados no cabeçalho significa que uma chamada para o método público pode ser completamente incorporada ao código real dos métodos privados, e o inlining não para com uma chamada para o método privado. Mesmo de uma unidade de compilação diferente (e métodos públicos geralmente seriam chamados de unidades de compilação diferentes).
É claro que também existe o motivo pelo qual o compilador não pode detectar problemas com a resolução de sobrecarga se não conhecer todos os métodos, inclusive os privados.
fonte
É para permitir que essas funções acessem os membros privados. Caso contrário, você precisará
friend
deles no cabeçalho de qualquer maneira.Se alguma função pudesse acessar os membros privados da classe, o privado seria inútil.
fonte