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
原创粉丝点击