Por que precisamos colocar membros privados em cabeçalhos?

57

As variáveis privadas são uma maneira de ocultar detalhes de complexidade e implementação para o usuário de uma classe. Este é um recurso bastante interessante. Mas eu não entendo porque em c ++ precisamos colocá-los no cabeçalho de uma classe. Eu vejo duas desvantagens irritantes para isso:

  • Ele desordena o cabeçalho do usuário
  • Força a recompilação de todas as bibliotecas do cliente sempre que as partes internas forem modificadas

Existe uma razão conceitual por trás desse requisito? É apenas para facilitar o trabalho do compilador?

    
por Simon 10.04.2012 / 11:25
fonte

3 respostas

65

É porque o compilador C ++ deve conhecer o tamanho real da classe para alocar a quantidade certa de memória na instanciação. E o tamanho inclui todos os membros, também os particulares.

Uma forma de evitar isso é usar o idioma Pimpl , explicado por Herb Sutter em sua série Guru of the Week # 24 e # 28 .

Atualizar

Na verdade, isso (ou mais geralmente, a distinção de cabeçalho / arquivo de origem e #include s) é um grande obstáculo em C ++, herdado de C. Nos dias anteriores, C ++ C foi criado, ainda não havia experiência com desenvolvimento de software em larga escala, onde isso começa a causar problemas reais. As lições aprendidas desde então foram atendidas por designers de linguagens mais novas, mas o C ++ está limitado por requisitos de compatibilidade retroativa, o que dificulta muito a abordagem de um problema tão fundamental na linguagem.

    
por 10.04.2012 / 11:53
fonte
15

A definição da classe precisa ser suficiente para o compilador produzir um layout idêntico na memória, onde quer que você tenha usado um objeto da classe. Por exemplo, dado algo como:

class X { 
    int a;
public:
    int b;
};

O compilador normalmente terá a no deslocamento 0 e b no deslocamento 4 . Se o compilador viu isso como apenas:

class X { 
public:
    int b;
};

Ele "pensaria" que b deveria estar no deslocamento 0 em vez do deslocamento 4. Quando o código usando essa definição atribuída a b , o código usando a primeira definição veria a get modified e vice-versa.

A maneira usual de minimizar os efeitos de fazer alterações nas partes privadas da classe geralmente é chamada de expressão idiomática (sobre a qual tenho certeza de que o Google pode fornecer muitas informações).

    
por 10.04.2012 / 11:57
fonte
3

Existem provavelmente várias razões. Embora os membros privados não possam ser acessados pela maioria das outras classes, eles ainda podem ser acessados por classes de amigos. Então, pelo menos nesse caso, eles podem ser necessários no cabeçalho, então a classe de amigos pode ver que eles existem.

A recompilação de arquivos dependentes pode depender da sua estrutura de inclusão. A inclusão dos arquivos .h em um arquivo .cpp em vez de outro cabeçalho pode, em alguns casos, impedir longas cadeias de recompilações.

    
por 10.04.2012 / 11:40
fonte

Tags