Fiquei me perguntando qual poderia ser o tamanho de um objeto de uma classe vazia . Certamente não poderia ter 0 bytes, pois deveria ser possível referenciá-lo e apontar para ele como qualquer outro objeto. Mas, quão grande é esse objeto?
Usei este pequeno programa:
#include <iostream>
using namespace std;
class Empty {};
int main()
{
Empty e;
cerr << sizeof(e) << endl;
return 0;
}
A saída que obtive nos compiladores Visual C ++ e Cygwin-g ++ foi de 1 byte ! Isso me surpreendeu um pouco, já que esperava que fosse do tamanho da palavra da máquina (32 bits ou 4 bytes).
Alguém pode explicar por que o tamanho de 1 byte? Por que não 4 bytes? Isso depende do compilador ou da máquina também? Além disso, alguém pode dar uma razão mais convincente de por que um objeto de classe vazio não terá o tamanho de 0 bytes?
Respostas:
Citando as Perguntas frequentes sobre estilo e técnica de C ++ de Bjarne Stroustrup , o motivo pelo qual o tamanho não é zero é "Para garantir que os endereços de dois objetos diferentes sejam diferentes." E o tamanho pode ser 1 porque o alinhamento não importa aqui, já que não há nada para realmente olhar.
fonte
new
; quando o espaço é alocado, outra alocação deve ter um endereço diferente. E assim por diante. Não há necessariamente nenhum ponteiro envolvido na classe vazia; pode haver ponteiros para as variáveis (ou referências, ou alocações locais / de pilha), mas eles não têm tamanho zero e não são necessariamente o tamanho do ponteiro.O padrão afirma que todos os objetos mais derivados têm sizeof ()> = 1:
fonte
Esse é realmente um detalhe de implementação. Uma vez, há muito tempo, pensei que poderia ser zero bytes ou mil bytes, que não tem relação com a especificação da linguagem. Mas, depois de olhar para o padrão (seção 5.3.3),
sizeof
é definido como sempre retornando um ou maior, não importa o quê.Isso é necessário para, entre outras coisas, permitir que você manipule matrizes de objetos e ponteiros para eles. Se fosse permitido que seus elementos tivessem tamanho zero,
&(array[0])
seriam idênticos a&(array[42])
, o que causaria todos os tipos de destruição em seus loops de processamento.O motivo pelo qual pode não ser uma palavra de máquina é que não há elementos dentro dela que realmente exigem que seja alinhada em um limite de palavra (como um inteiro). Por exemplo, se você colocar
char x; int y;
dentro da classe, meu GCC a registra em oito bytes (já que o segundo int deve estar alinhado nessa implementação).fonte
Há uma exceção: matrizes de comprimento 0
fonte
c
,&c[M] == &c[N]
para cadaM
eN
(clang ++ 4.1).Embora não seja necessário atribuir nenhuma memória para uma classe vazia, mas para fazer objetos de classes vazias, o compilador atribui a memória mínima que pode ser atribuída, que é 1 byte. Desta forma, o compilador pode distinguir dois objetos da mesma classe vazia de forma única, e será capaz de atribuir o endereço do objeto a um ponteiro do tipo de classe vazia.
fonte
Acho que também pode ser útil incluir um link para uma resposta que explique isso. É sobre
boost::compressed_pair
por Logan Capaldo .fonte
Isso pode ajudar u :-) http://bytes.com/topic/c/insights/660463-sizeof-empty-class-structure-1-a
fonte
A alocação de 1 byte para uma classe vazia depende do compilador. Os compiladores precisam ter certeza de que os objetos residem em diferentes locais da memória e precisam alocar um tamanho de memória diferente de zero para um objeto. Ouça as notas sobre este tópico aqui: http://listenvoice.com/listenVoiceNote.aspx?id=27
Mesmo que os compiladores aloquem um tamanho diferente de zero para uma classe vazia, eles também fazem otimizações quando novas classes são derivadas de classes vazias. Ouça sobre a otimização de base vazia nas perguntas da entrevista de programação em c ++ do ListenVoice.
fonte
a razão para a classe sem membros de dados, mas com tamanho de 1 byte é que este * texto forte * deve ser armazenado na memória para que uma referência ou ponteiro possa apontar para o objeto daquela classe
fonte
classe vazia - essa classe não contém nenhum conteúdo.
qualquer classe que não esteja vazia será representada por seu conteúdo na memória.
agora, como a classe vazia será representada na memória? como não tem conteúdo não tem como mostrar sua existência na memória, mas a classe está presente, é obrigatório mostrar sua presença na memória. Para mostrar a presença de uma classe vazia na memória, é necessário 1 byte.
fonte
Eu acho que é assim porque 1 byte é a menor unidade de memória que pode ser usada como um espaço reservado, e não pode dar tamanho zero, pois não será possível criar uma matriz de objetos.
e a coisa que você disse "Isso me surpreendeu um pouco, pois esperava que fosse do tamanho da palavra de máquina (32 bits ou 4 bytes)." será verdadeiro para a variável de referência (palavras macine) do tipo empty (), não o tamanho da própria classe (que é um tipo de dado abstrato),
fonte
Acho que essa questão é apenas de interesse teórico, mas não importa na prática.
Como já foi apontado por outros, derivar de uma classe vazia não faz mal nenhum, pois isso não consumirá nenhuma memória extra para a porção da classe base.
Além disso, se uma classe estiver vazia (o que significa que - teoricamente - não precisa de nenhuma memória por instância, ou seja, não tem nenhum membro de dados não estático ou funções de membro virtuais), então todas as suas funções de membro também podem (e deve) ser definido como estático. Portanto, não há necessidade de criar uma instância dessa classe.
Resumindo: se você estiver escrevendo uma classe X vazia, torne todas as funções-membro estáticas. Você não precisará criar objetos X, e as classes derivadas não serão afetadas de forma alguma.
fonte
Resultado: OK, não há problema em ter endereços diferentes
Retornar o tamanho 1 garante que os dois objetos não terão o mesmo endereço.
fonte
É diferente de zero para garantir que os dois objetos diferentes terão endereços diferentes. Objetos diferentes devem ter endereços diferentes, portanto, o tamanho de uma classe vazia é sempre de 1 byte.
fonte
Acho que se o tamanho de uma classe vazia for zero, significa que ela não existe. Para que ele (classe) exista, é necessário ter pelo menos 1 byte, pois esse byte é o endereço de memória / referência.
fonte
É por causa deste ponteiro, embora o ponteiro seja (inteiro) de 4 bytes, mas se refere a um local de memória (uma unidade) que é 1 byte.
fonte