cpp——隐式转换——类类型
来源:互联网 发布:警方破特大网络赌球 编辑:程序博客网 时间:2024/05/02 00:02
概述
#pragma pack(4)class CAnimal{public: char name[3]; short age; int color; char gender;};class CDog : public CAnimal{public: int hurt;};void mem_offset(){ CAnimal animal; CDog dog; cout << "-----animal-----" << endl; cout << "sizeof(animal) = " << sizeof(animal) << endl; cout << "name offset = " << (char*)animal.name - (char*)&animal << endl; cout << "age offset = " << (char*)&animal.age - (char*)&animal << endl; cout << "color offset = " << (char*)&animal.color - (char*)&animal << endl; cout << "gender offset = " << (char*)&animal.gender - (char*)&animal << endl; cout << "-----dog-----" << endl; cout << "sizeof(dog) = " << sizeof(dog) << endl; cout << "name offset = " << (char*)dog.name - (char*)&dog << endl; cout << "age offset = " << (char*)&dog.age - (char*)&dog << endl; cout << "color offset = " << (char*)&dog.color - (char*)&dog << endl; cout << "gender offset = " << (char*)&dog.gender - (char*)&dog << endl; cout << "hurt offset = " << (char*)&dog.hurt - (char*)&dog << endl;}
output:
-----animal-----sizeof(animal) = 16name offset = 0age offset = 4color offset = 8gender offset = 12-----dog-----sizeof(dog) = 20name offset = 0age offset = 4color offset = 8gender offset = 12hurt offset = 16
分析:
- 每个类会生成对应的c struct,c struct中的数据成员在内存中布局顺序与数据成员在类定义中的顺序一致
- 子类的c struct在父类的c struct末尾添加自身的数据成员
类的这种内存布局确保了子类不会改变父类数据成员相对于父类struct首地址的offset,因此把子类指针赋值给父类指针是安全的,因为父类指针通过数据成员的offset能寻址到正确的内存空间
类隐式转换
子类指针隐式转换为父类指针是安全的,引用的本质是const对象,因此子类赋值给父类引用也是安全的
class CAnimal{public: CAnimal() { cout << "CAnimal()" << endl; } CAnimal(const CAnimal &other) { cout << "CAnimal(const CAnimal &other)" << endl; } public: CAnimal& operator=(const CAnimal &other) { cout << "CAnimal operator=" << endl; return *this; } public: void info() { cout << "CAnimal info()" << endl; }};class CDog : public CAnimal{public: CDog() { cout << "CDog()" << endl; } CDog(const CDog &other) : CAnimal(other) { cout << "CDog(const CDog &other)" << endl; } public: CDog& operator=(const CDog &other) { CAnimal::operator=(other); cout << "CDog operator=" << endl; return *this; }};void class_convert(){ CDog dog; CAnimal* pAnimal = &dog; CAnimal* rAnimal = &dog; pAnimal->info(); rAnimal->info(); CAnimal animal = dog; animal = dog;}
output:
CAnimal()CDog()CAnimal info()CAnimal info()CAnimal(const CAnimal &other)CAnimal operator=
结论:
- 子类对象初始化父类对象的本质是调用父类的复制构造函数
- 子类对象赋值给父类对象的本质是调用父类的赋值操作符函数
0 0
- cpp——隐式转换——类类型
- cpp——显式类型转换
- cpp——类——嵌套类型 嵌套类 局部类型 局部类
- JavaScript数据转换四——隐式类型转换
- 类型转换(1)— 隐式转换
- Javascript—类型转换
- cpp 类型转换
- cpp中的类型转换
- cpp的类型转换
- java——隐式转换——类类型
- oc——隐式转换——类类型
- cpp——复合类型——引用
- 恶补Cpp系列——标准vector类型
- 类型转换(2)— 强制转换
- c——显式类型转换
- C#——类型转换
- C#——类型转换
- Struts2——类型转换
- JQueryEasyUI 表单验证之验证框(非空验证)
- POJ 2386 Lake Counting
- basic algorithm in python
- Android中Service#onStartCommand方法的返回值
- Android广播机制二
- cpp——隐式转换——类类型
- 算法训练 字串统计
- SElinux 读懂.te 定义自己的 .te
- Android最简单的方式实现MVP
- Spring MVC 和Struts2的区别,一点想法
- Mysql常用语句
- python 借用Jpype调用stanford parser
- C++拷贝构造函数详解
- 页面上报错:Invalid left-hand side in assignment