您的位置:首页 > 编程语言 > C语言/C++

C++类成员布局

2015-08-09 15:15 351 查看
在C++中对象的内存布局与类成员声明的顺序一致,静态成员放在数据区(Data Section)而非对象内存中,若多个类静态成员名称相同,C++则按照name mangling技术进行重命名保证名称的唯一性。若类之间发生了继承关系(无虚拟指针无虚继承)时,按照基类、子类成员顺序排列,另在C++对象复制中,有一个规则:基类子对象(base class object)在派生类(derived class member)中成员的原样性

测试代码如下:

#include <iostream>
#include <iomanip>
#include <cassert>

using namespace std;

class Concrete1 {
public:
void foo(void) {
cout << "concrete1:" << bit1 << endl;
}
Concrete1():val(1),bit1('a') {
}
public:
int val;
char bit1;
};

class Concrete2:public Concrete1 {
public:
char bit2;
public:
void foo(void) {
cout << "concreate2" << bit2 << endl;
}

Concrete2():bit2('b'),Concrete1() {
}
};

class Concrete3: public Concrete2 {
public:
void foo(void) {
cout << "concrete3:" << bit3 << endl;
}

Concrete3():bit3('c'),Concrete2() {
}

public:
char bit3;
};

template <class data_type1,class data_type2>
const char *access_order(data_type1 *mem1,data_type2 *mem2)
{
unsigned long p1,p2;

p1 = (unsigned long)(mem1);
p2 = (unsigned long)(mem2);

assert(p1 != p2);

return p1 < p2
? "member 1 occurs first"
:"member 2 occurs first";
}

int main(int argc, char *argv[])
{
Concrete2 c2,*pc2;
Concrete1 c1,*pc1_1,*pc1_2;
Concrete3 c3;

pc2 = &c3;
pc1_1 = pc2;
pc1_2 = &c1;
char *b;

//access_order(&Concrete1::bit1,&Concrete1::bit);
cout << "address val  and bit1:" << access_order(&c1.val,&c1.bit1) << endl;
cout << "Concrete3:" << sizeof(Concrete3) << endl;

//b = *(char *)((char *)(&(pc1_2->bit1)) + 1);
b = &(pc1_2->bit1);

cout << "Before address:" << hex << static_cast<void *>(b) << ",b:" << *b << endl;
b++;
cout << "After address:" << hex << static_cast<void *>(b) << endl;
cout << "b:" << *b << "b+1:" << *(b+1)<< endl;
cout << "Memberwise copy." << endl;
*pc1_2 = *pc1_1;
//b = *(char *)((char *)(&(pc1_2->bit1)) + 1);
b = &(pc1_2->bit1);

cout << "Before address:" << hex << static_cast<void *>(b) << ",b:" << *b << endl;
b++;
cout << "After address:" << hex << static_cast<void *>(b) << endl;
cout << "b:" << *b << "b+1:" << *(b+1)<< endl;
pc1_2->foo();

return 0;
}


g++ 运行情况如下:

f:\code\C++\study>concrete
concrete
address val  and bit1:member 1 occurs first
Concrete1:8//三个类大小均为8字节
Concrete2:8
Concrete3:8
Before address:0x22ff34,b:a
After address:0x22ff35
b: b+1:"
Memberwise copy. //复制前后Concrete1对象填充字节内容未变化
Before address:0x22ff34,b:a
After address:0x22ff35
b: b+1:"
concrete1:a


vs2010运行如下:

testlayout
address val  and bit1:member 1 occurs first
Concrete1:8//三个类大小均不同,采用了对齐方式处理
Concrete2:12
Concrete3:16
Before address:0012FF40,b:a
After address:0012FF41
b:蘠+1:
Memberwise copy. //复制前后Concrete1对象填充字节内容未变化
Before address:0012FF40,b:a
After address:0012FF41
b:蘠+1:
concrete1:a
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: