Tamanho de Classes Vazias e Comportamento de Construtores Padrão em C++

Em C++, uma classe sem membros de dados frequentemente resulta em um tamanho de instância de 1 byte. Isso ocorre porque o compilador precisa garantir que diferentes objetos tenham endereços de memória distintos, mesmo que não contenham dados. Vamos explorar como os construtores padrão se comportam nesse contexto.

Considere uma estrutura vazia:

struct EstruturaVazia {
};

int main() {
    EstruturaVazia obj;
    std::cout << sizeof(obj);
    return 0;
}

Ao executar esse código, o tamenho impreso será 1. Ao inspecionar o código assembly gerado, nota-se que a instanciação de obj não envolve chamadas a construtores—o compilador apenas aloca espaço para o objeto.

EstruturaVazia obj;
std::cout << sizeof(obj);
; Código assembly resultante (exemplo simplificado):
; O tamanho 1 é passado diretamente para a função de saída, sem operações adicionais.

Agora, ao alocar um objeto na heap:

EstruturaVazia* ptr = new EstruturaVazia();
std::cout << sizeof(*ptr);

Novamente, o tamanho é 1. O código assembly mostra que new aloca 1 byte, mas nenhuma chamada a construtores é feita, já que a classe não define nenhum. O endereço alocado contém um valor como 0xCD (205 em decimal), que é típico de memória não inicializada em certos ambientes.

Para comparar, adicione um construtor explícito:

struct EstruturaComConstrutor {
    EstruturaComConstrutor() {}
};

EstruturaComConstrutor obj2;
std::cout << sizeof(obj2);
EstruturaComConstrutor* ptr2 = new EstruturaComConstrutor();
std::cout << sizeof(*ptr2);

Agora, o código assembly revela chamadas ao construtor definido pelo usuário, tanto na alocação na stack quanto na heap. No entanto, o tamanho permanece 1 byte, pois não há membros de dados.

; Exemplo de assembly para EstruturaComConstrutor obj2:
; call para o endereço do construtor antes de usar o objeto.

Isso demonstra que, sem um construtor definido, o compilador pode não gerar um construtor padrão automaticamente. Em classes vazias, a instância ocupa 1 byte, e a alocação não envolve inicialização de membros.

Agora, adicione um membro de dados com inicialização:

struct EstruturaComDado {
    int valor = 42;
};

EstruturaComDado obj3;
std::cout << sizeof(obj3);
EstruturaComDado* ptr3 = new EstruturaComDado();
std::cout << sizeof(*ptr3);

Neste caso, o tamanho aumenta para 4 bytes (tamanho de um int), e o código assemb mostra que o compilador gera um construtor para inicializar valor com 42. A chamada ao construtor ocorre tanto na stack quanto na heap.

; Código assembly para EstruturaComDado obj3:
; call para construtor que inicializa valor=42 antes de prosseguir.

Tags: C++ Construtor Padrão Classe Vazia Tamanho de Objeto Compilador C++

Publicado em 8-9 10:32