2013-10-10 66 views
0

今天,我读取<> .I遇到problem.as书上说,G ++对象模型

class Concrete1 { 
public: 
int val; 
char bit1; 
}; 

class Concrete2 : public Concrete1 { 
public: 
char bit2; 
}; 

class Concrete3 : public Concrete2 { 
public: 
char bit3; 
}; 
当我运行中的mingw克++代码

,三种类别的空间是8,12,但是当我在vs2012中运行代码时,三个类的空间都是8,12,16。在vs2012中的代码没有问题。但对于g ++中的空间,我有一些问题,而我尝试写一个示例代码来查看是否有问题。示例代码如下:

int main(void) 
{ 
    Concrete2 con2; 
    memset(&con2, 0, sizeof(con2)); 
    Concrete3 con3; 
    con3.val = 3; 
    con3.bit2 = 4; 
    con3.bit3 = 5; 
    Concrete2* con_ptr2 = &con2; 
    Concrete2* con_ptr3 = &con3; 
    *con_ptr3 = *con_ptr2; 
    cout << con3.bit3<< endl; 
    cout << sizeof(Concrete1) << endl; 
    cout << sizeof(Concrete2) << endl; 
    cout << sizeof(Concrete3) << endl; 
    return 0; 
} 

和以g ++对象模型,代码与代码后无problem.why “* con_ptr3 = * con_ptr2;” 时,con3.bit3是5不为0? 任何人都可以帮助我吗?

+0

设置一个断点,一步一步完成。 – nhgrif

+0

我hava设置了一个断点,我看到了结果,但我不知道如何解释结果! – user2861706

+0

每行中每个指针和变量的值是什么? – nhgrif

回答

0

似乎结果是正确的,bit3应该是5,因为该赋值只影响con3的Concrete1和Concrete2部分。

赋值是成员方式,而不是字节方式。 所以“* com_ptr3 = * con_ptr2”与“memcpy(con_ptr3,con_ptr2,sizeof(Concrete2))” 不一样默认的复制构造函数和默认赋值操作符必须以成员身份和成员顺序复制数据在课堂上定义。 这也意味着你不能指望具有任何特定值的填充字节。

大小的差异只是因为VS和gcc处理填充略有不同。 gcc显然能够将bit2和bit3打包成相同的32位字,而VS不会。 奇怪的是,海湾合作委员会也不能还包装bit1,导致规模8,8,8。

这可能是因为gcc认为Concrete1是POD,但是具体的2和3不是。该标准对于POD类型与非POD类型数据的布局有着更严格的要求。编译器在非pod类型的类数据布局中具有更多的灵活性。