C++类成员布局

在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

posted on 2015-08-09 15:15  kkford  阅读(343)  评论(0编辑  收藏  举报

导航