作者:小心大巧 | 来源:互联网 | 2023-05-19 07:35
在C++中对象的内存布局与类成员声明的顺序一致,静态成员放在数据区(DataSection)而非对象内存中,若多个类静态成员名称相同,C++则按照namemangling技术进行重命名保证名称的唯
在C++中对象的内存布局与类成员声明的顺序一致,静态成员放在数据区(Data Section)而非对象内存中,若多个类静态成员名称相同,C++则按照name mangling技术进行重命名保证名称的唯一性。若类之间发生了继承关系(无虚拟指针无虚继承)时,按照基类、子类成员顺序排列,另在C++对象复制中,有一个规则:基类子对象(base class object)在派生类(derived class member)中成员的原样性。
测试代码如下:
#include
#include
#include
using namespace std;
class Concrete1 {
public:
void foo(void) {
cout <<"concrete1:" <}
Concrete1():val(1),bit1('a') {
}
public:
int val;
char bit1;
};
class Concrete2:public Concrete1 {
public:
char bit2;
public:
void foo(void) {
cout <<"concreate2" <}
Concrete2():bit2('b'),Concrete1() {
}
};
class Concrete3: public Concrete2 {
public:
void foo(void) {
cout <<"concrete3:" <}
Concrete3():bit3('c'),Concrete2() {
}
public:
char bit3;
};
template
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 ? "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:" <cout <<"Concrete3:" <
//b = *(char *)((char *)(&(pc1_2->bit1)) + 1);
b = &(pc1_2->bit1);
cout <<"Before address:" <(b) <<",b:" <<*b <b++;
cout <<"After address:" <(b) <cout <<"b:" <<*b <<"b+1:" <<*(b+1)<cout <<"Memberwise copy." <*pc1_2 = *pc1_1;
//b = *(char *)((char *)(&(pc1_2->bit1)) + 1);
b = &(pc1_2->bit1);
cout <<"Before address:" <(b) <<",b:" <<*b <b++;
cout <<"After address:" <(b) <cout <<"b:" <<*b <<"b+1:" <<*(b+1)<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