C++类模型漫谈(一)

系统基于32位,MSVC编译器,VS开发工具

1、一个简单的类型TypeA,类型对象a_obj总共占8个字节。char类型a1占1个字节,但是为了考虑到32位系统存储效率,所以a1变量后面会分配3个字节,用于内存的4字节对齐。

a2变量占用4个字节,对象a_obj的地址等于a1的地址。成员函数TypeA::TypeA_Method不占用该对象的内存空间。

class TypeA {
public:
	char a1 = 10;
	int a2 = 20;
	void TypeA_Method() {}
};
int main()
{   
	TypeA a_obj;
	cout << sizeof(a_obj) << endl;//输出8
	return 1;
}

2、从TypeA类型继承一个派生类TypeB,这时TypeB的对象b_obj不仅包含了自己的成员变量b1、b2还包含了继承而来的TypeA成员a1、a2。TypeA子对象部分排在前面低地址处,对象b_ob的地址等于a1的地址

因为包含了继承而来的TypeA部分,所以b_obj总共占16个字节。

class TypeA {
public:
	char a1 = 10;
	int a2 = 20;
	void TypeA_Method() {}
};
class TypeB:public TypeA{
public:
	char b1 = 30;
	int b2 = 40;
	void TypeB_Method() {}
};
int main()
{   
	TypeA a_obj;
	cout << sizeof(a_obj) << endl;//输出8
	TypeB b_obj;
	cout << sizeof(b_obj) << endl;//输出16
	return 1;
}

3、把上面2个不同类型的对象相互赋值,因为TypeB继承自TypeA,所以TypeB内存空间是是大于等于TypeA的,所以把TypeB类型对象赋值给TypeA类型对象不会出任何问题,反过来就不行。

当然当你写a_obj=b_obj的时候,编译器通常会生成一个赋值构造函数,函数里面会将b_obj的TypeA基类子对象部分数据复制给a_obj

int main()
{   
    TypeA a_obj;
    TypeB b_obj;

    a_obj = b_obj;//把派生类b_obj对象赋值给基类a_obj对象
    b_obj = a_obj;//把基类a_obj对象赋值给派生类b_obj对象(错误)
   
    return 1;
}
 

4、把两个类型对象的指针,互相赋值,赋值的是一个地址,转换成相应类型的指针,指向不同的内存空间。因为TypeB是继承自TypeA,b_obj空间自然大于等于a_obj,这样将&b_obj赋值给a_ptr不会有问题。

反过来的赋值,则只能通过强制类型转换,而且不保证安全。

int main()
{   

	TypeA a_obj;
	TypeB b_obj;

	TypeA* a_ptr = &b_obj;//把派生类b_obj的指针赋值给TypeA*类型指针a_ptr
	TypeB* b_ptr = (TypeB*)&a_obj;//把基类a_obj的指针强制赋值给TypeB*类型指针b_ptr

	return 1;

}

 

posted @ 2022-10-18 18:23  自由小菜园  阅读(26)  评论(0编辑  收藏  举报