{
public:
Aclass();
virtual ~Aclass();
};
AClass的大小为4是因为你的析构函数被定义为虚拟的,这就引入了一个隐含的虚表指针成员,32位平台上,指针的大小为4字节;
当你将virtual ~Aclass改为~Aclass时,Aclass中就没有定义虚函数表,自然也就没有虚表指针成员了.这种情况下,由于你的类没有定义数据成员,也就是说他没有占据存储空间,但是由于当创建一个对象时,要标识一个对象,必须通过给它分配存储空间来引用对象,两者权衡之下,就给它分配了一个字节的存储空间.
class User
{
public:
int id;
std::string name;
User();
virtual ~User();
operator bool() const {if (id) return true; return false;}
};
你可以这样考虑,对于普通的类型的成员,比如所int,double,float等,它占据的尺寸是该类型变量所对应的大小与与编译器相关的地址对齐的综合效果,
如果是一个某一类型的指针或引用类型的变量,它的大小在32位平台上就是4个字节.
任何一个类,最终总要归结到这些基础数据类型上去.
比如string类,要实现它的功能,它里面就定义了一个char*类型的指针,指向数据存储区.
class string
{
private:
char* data; //某一个缓冲区的指针
}
上面的应当就是string类型的定义,它的尺寸应当为4字节.
其他的类的尺寸就是由它所包容的类的实例的尺寸一成一层累加起来的(考虑对齐因素);string的尺寸与与其相关联的存储区的大小没有关系.
Inside c++ object model里面有介绍;
placement new比较麻烦,得重载new delete new[] delete[],需求是如何产生的?
可以归纳以下几个原则:
1.类的大小为类的非静态成员数据的类型大小之和,也就是说静态成员数据不作考虑。
2.普通成员函数与sizeof无关。
3.虚函数由于要维护在虚函数表,所以要占据一个指针大小,也就是4字节。
4.类的总大小也遵守类似class字节对齐的,调整规则。
- class Base
- {
- public:
- Base(){};
- virtual ~Base(){};
- void set_num(int num)
- {
- a=num;
- }
- virtual int get_num()
- {
- return a;
- }
- private:
- int a;
- char *p;
- };
- class Derive:public Base
- {
- public:
- Derive():Base(){};
- ~Derive(){};
- virtual int get_num()
- {
- return d;
- }
- private:
- static int st;
- int d;
- char *p;
- char c;
- };
- int main()
- {
- cout<<sizeof(Base)<<endl;
- cout<<sizeof(Derive)<<endl;
- return 0;
- }
在Base类里添加了virtual int get_num()函数,而子类也重新实现了virtual int get_num()函数。
但是结果依然是
12
24
说明子类只是共用父类的虚函数表,因此一旦父类里有虚函数,子类的虚函数将不计入sizeof大小。
这可以认为是一个补充规则。