Chinaunix

标题: sizeof(对象)的两个疑问,求答案 [打印本页]

作者: jeanlove    时间: 2009-02-01 17:13
标题: sizeof(对象)的两个疑问,求答案
(1)用gcc编译出来的空对象大小是1个字节,这1个字节的占位符号有什么实际的意义吗? 我上网搜了一下,似乎其他的编译器有的生成的控对象有4个字节的,不一定都相同。这个1字节浪费了?
(2) 一个具有虚函数表的对象,为什么无论有多少个虚函数,size都是只增加了4?

===================================
下面这样一小段代码
#include <cstdlib>
#include <cstdio>
using namespace std;
class c1{
public:
    c1(){}
    ~c1(){}
};
struct c2{
};
class B{
      int x;
      virtual void f(){} ----->如果B类没有g函数和h函数,B的大小是8,有了g和h,B的大小还是8!!!!!!!!!!!!!!!!!!
      virtual void g(){}
      virtual void h(){}
};
int main(int argc, char *argv[])
{
    c1 j;
    printf("sizeof j=%d\n",sizeof(j));
    c2 k;
    printf("sizeof k=%d\n",sizeof(k));
    printf("sizeof B=%d\n",sizeof(B));
    B b1;
    printf("sizeof b1=%d\n",sizeof(b1));
}
输出是
ctor
sizeof j=1
sizeof k=1
sizeof B=8
sizeof b1=8
Press any key to continue . . .

10分求上面两个问题的答案! 谢谢!

[ 本帖最后由 jeanlove 于 2009-2-1 17:17 编辑 ]
作者: 5毛党党员    时间: 2009-02-01 17:13
原帖由 jeanlove 于 2009-2-1 17:26 发表

难道虚表不是一个对象一个吗? 如果是静态的方在某个特定的地址上,对象只包含一个指向它的指针,那么就无法动态生成对各对象了呀!
虚表有多少个函数入口,对象就增加多大吧??

谢谢

虚表会增大。。。可是虚表的地址长度不会变啊
作者: 思一克    时间: 2009-02-01 17:18
函数物理上不包含在CLASS之内。
作者: 5毛党党员    时间: 2009-02-01 17:19
(2)那个4是虚表指针吧?
作者: jeanlove    时间: 2009-02-01 17:23
原帖由 思一克 于 2009-2-1 17:18 发表
函数物理上不包含在CLASS之内。

但是不是说虚函数表里面,每个虚函数对应一项吗? (就像c语言的struct包含几个函数指针一样),sizeof求得的大小应该增加吧?

谢谢
作者: 5毛党党员    时间: 2009-02-01 17:24
原帖由 jeanlove 于 2009-2-1 17:23 发表

但是不是说虚函数表里面,每个虚函数对应一项吗? (就像c语言的struct包含几个函数指针一样),sizeof求得的大小应该增加吧?

谢谢

所以class里只要有一个虚函数表的指针就可以了
作者: jeanlove    时间: 2009-02-01 17:26
原帖由 5毛党党员 于 2009-2-1 17:19 发表
(2)那个4是虚表指针吧?

难道虚表不是一个对象一个吗? 如果是静态的方在某个特定的地址上,对象只包含一个指向它的指针,那么就无法动态生成对各对象了呀!
虚表有多少个函数入口,对象就增加多大吧??

谢谢
作者: 思一克    时间: 2009-02-01 17:27
函数,虚的实的都不在CLASS里面。感觉在是编译层面的,不是物理真实。
如有函数指针,就占空间了。

原帖由 jeanlove 于 2009-2-1 17:23 发表

但是不是说虚函数表里面,每个虚函数对应一项吗? (就像c语言的struct包含几个函数指针一样),sizeof求得的大小应该增加吧?

谢谢

作者: alexhappy    时间: 2009-02-01 17:43
父类只会保留一个指向虚表的指针,而虚表却可以变化,虚表里指向虚函数实现(这是要动态确定的),具体解释参见《深入浅出MFC》我记的不清
你可以试试用C继承B,然后在sizeof看看C的对象大小
作者: jeanlove    时间: 2009-02-01 17:44
原帖由 5毛党党员 于 2009-2-1 17:29 发表

虚表会增大。。。可是虚表的地址长度不会变啊

OK, 我知道你的意思了

就是B类的对象b1包括两个域,一个是数据x, 另一个是指向虚表的指针。虚表指针的值是new的时候指定的类型所创建的,而那个类型究竟是谁,放在哪里就不是很重要了。那个虚表并不是实例的一部分,这个和用struct加几个函数指针的用法还不完全一样,两次跳转了。

另一个问题: 空对象占1个字节有什么实际意义吗? 谢谢5毛党党员dx
作者: swxlion    时间: 2009-02-10 14:58
空对象占1,这个记得好像是New规定的。如果占0,那好,返回一个指针a,指向的空间大小为0,地址假设为0x12345678(32 bits OS);那之后我在new char[1024];好,这下需要返回一个新的地址b。因为在堆(同一个堆,因为没有专门的另行所制定,这对很多程序也是常见情形)上面前一个地址用到了0x12345677这里(因为前面的new空对象返回的指针a指向0x12345678,而a所指向的空间大小为0,所以0x12345678这个地址仍就可以用,所以上一个地址用到的地方不会超过0x12345677),好,0x12345678还是可以用的,而且还是内存对齐的地址。好,没什么再好犹豫的,于是返回的b也指向这里——0x12345678。于是,指针a、b指向同一个地址,但却指向不同的对象,这两个对象间没有任何的继承啊,派生啊之类乱七八糟的关系。也就是说,这两个对象之间的关系很单纯。恩,明白问题了么~~~~~
作者: egmkang    时间: 2009-02-12 00:34
Inside  the C++ Object Model




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2