O mistério do sizeof – parte 2
Código Fonte:
#include <cstdlib>
#include <iostream>
using namespace std;
class Base {
public:
void f() {}
};
class BaseV {
public:
virtual void f() {}
};
class Derivada: public Base {
public:
void f() {}
private:
int x;
};
class DerivadaV: public Base {
public:
virtual void f() {}
private:
int x;
};
int main(int argc, char *argv[])
{
Base b;
BaseV bv;
Derivada d;
DerivadaV dv;
cout << "sizeof Base : " << sizeof( b ) << endl;
cout << "sizeof BaseV : " << sizeof( bv ) << endl;
cout << "sizeof Derivada : " << sizeof( d ) << endl;
cout << "sizeof DerivadaV: " << sizeof( dv ) << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
|
Saída:
sizeof Base : 1 sizeof BaseV : 4 sizeof Derivada : 4 sizeof DerivadaV: 8 |
Detalhes:
Novamente, como vimos na parte 1 desse post, a classe vazia ocupa pelo menos um byte. Porém, quando essa classe possui um método virtual, passa a ocupar 4 bytes… O mesmo ocorre com a classe derivada, quando acrescentamos um método virtual seu tamanho passa de 4 ( sizeof(int) ) para 8 bytes.
Uma função não ocupa espaço no objeto. Porém uma função virtual irá criar uma VMT (virtual method table) que é na realidade um ponteiro, e que ocupa 4 bytes (nesse compilador). Toda classe que possui (ou herda) pelo menos um método virtual irá ter uma VMT, o que significa que seu tamanho será aumentado no tamanho de um ponteiro. A exceção são as classes vazias, sem atributos, que passarão ter o tamanho de um ponteiro – nesse caso, não é necessário que o compilador force um tamanho diferente de zero.
That’s all, folks!
[...] vimos neste outro post, mesmo que uma classe ou estrutura não contenha atributos ela deve ocupar pelo menos um byte. [...]