为什么这个类的size是4?类中有虚函数

chinalupin 2008-02-03 05:17:31
程序如下:
#include <iostream>
#include <complex>
using namespace std;
class Base{
public:
Base(){}
~Base(){}
virtual void f(int){}
virtual void f(double){}
virtual void g(int i=10){}}
void g2(int i=10){}
};//函数具体内容不写了,无关紧要

int main(){
Base b;
cout<<sizeof(Base)<<endl;
}

为什么输出是4?我试过,当我把里面的虚函数去掉后,输出是1
...全文
252 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
meiZiNick 2008-05-01
  • 打赏
  • 举报
回复
我也想知道,正在找這方面的資料~~~~~
qiuqiu173 2008-03-07
  • 打赏
  • 举报
回复
指针的大小是四个字节
Supper_Jerry 2008-03-07
  • 打赏
  • 举报
回复
分都被抢没了!!楼主给我发点。
星羽 2008-03-07
  • 打赏
  • 举报
回复


#include "iostream"
using namespace std;

struct normal {

};

struct base {
virtual void fun() {
}
};

struct dev : public base {

};

struct vev : virtual public base {

};

int main()
{
cout<<sizeof(normal)<<endl;
cout<<sizeof(base)<<endl;
cout<<sizeof(dev)<<endl;
cout<<sizeof(vev)<<endl;

return 0;
}


结果是
1
4
4
8

对于空结构/类,为了寻址,其必须有大小,在win32上最小的单位是1BYTE,所以 是 1
你可以设想如果大小是0回出现的各种问题,比如

normal* p = new normal[100];

p++ 等于多少呢??



对于有序函数的class,由于需要存储虚表,所以需要4字节的vtable指针,对于不同的
编译器,vtable指针的位置不同,vc一般在类的数据最前面


对于虚继承,除了vtable还需要一个4字节的 virtual base class table

详细了解你可以看看这个

http://htm.winsteps.net/program/5724.htm
Seanxiaoxiao 2008-03-07
  • 打赏
  • 举报
回复
恩,楼主可以试着调试,然后看内存的布局,的确像这样定义,会出现一个vptr
liwei84516 2008-03-07
  • 打赏
  • 举报
回复
学习了,接分接分
ttkk_2007 2008-03-07
  • 打赏
  • 举报
回复
要求一个类占多少内存,你只需看这个类中是否有nonstatic data member和虚函数,不用考虑函数(包括静态的),你的类里面只有虚函数,所以他只有一个vptr占用的4个字节以指向vtable,去掉虚函数,你的sizeof(Base)是0不是1,是因为他要为每个对象分配一个字节的char,用以区分各个对象,否则无法区分
waterathena 2008-03-07
  • 打赏
  • 举报
回复
因为类中没有什么数据类型成员变量存储;
但是有虚函数表的指针要存储。指针的大小为机器字长:4;
其实C#里面已经取消了对类的进行sizeof操作。还是那样比较好理解。
michney 2008-02-04
  • 打赏
  • 举报
回复
虚函数表的指针啊
vptr
bluegift 2008-02-04
  • 打赏
  • 举报
回复
(Inside the C++ Object Model 书中说了

1. 一个类什么属性也没有,生成对象时编译器为了和空值区别,自动加了一个字节
2. 有虚函数的类,生成对象时,自动为对象插入一个虚表指针(指向vtable的指针),一个指针在32为操作系统中刚好为4字节。
3. vtable不在对象之中,在内存另一个区域。
ssdx 2008-02-03
  • 打赏
  • 举报
回复
上面说了为什么是4

至于为什么是1 是因为 类里面什么都没有 编译器会添加一个char标识。
小小的王药师 2008-02-03
  • 打赏
  • 举报
回复
推荐:
Inside the C++ Object Model
By Stanley B. Lippman
Publisher : Addison Wesley
阿呆_ 2008-02-03
  • 打赏
  • 举报
回复
1. vtable和常量字符串一样是放在只读数据段中的. 每个有虚函数的类对应一个vtable
2. 类的对象在内存中的布局相当于:
struct
{
void * vtb;
};

注意, vtable是针对类的, 而不是针对类的对象, 同一个类的所有对象的vtable都指向一个地方.
vtable中的具体布局要看编译器怎么定的了, vtable内包含了该类所有虚函数的入口地址或代码(比如jmp xxxxx), 另外一般都会有指针指向子类和父类的vtable. 还要注意一点就是vtable中只包含虚函数的入口地址而不包含普通成员函数(调用类的普通成员函数在编译期就和调用普通函数一样被编译成直接调用的代码了, 所以严格点说到了运行时已经不能得知某个类具体有哪些成员函数了)
chinalupin 2008-02-03
  • 打赏
  • 举报
回复
就是说当一个类中含有虚函数时,系统会自动创建一个vtb,然后在类里面添加一个成员,是指向这个vtb的指针。是这样吗?

那么,
1 在内存中这个vtb是放在什么地方呢?
2 这个类的对象在内存中是这样放的吗?
----------
vtb
Base()
~Base()
f(int)
f(double)
g(int i=10)
g2(int i=10)
----------
oo 2008-02-03
  • 打赏
  • 举报
回复
你希望多大?

4字节刚好放一个vtable指针
曲调虚函数,当然就不需要vtable指针了,是1不是0是不能有长度为0的object

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧