c++ 子类与父类之间的类型转换

子类与父类之间的类型转换

先给一段代码

class Base {
    public:
        int a = 10;
};

class pub_Derv : public Base {
    Base *getBase() {return this;}
};

class prot_Derv : protected Base {
    Base *getBase() {return this;}
};

class priv_Derv : private Base {
    Base *getBase() {return this;}
};

class pub_pub_Derv : public pub_Derv {
   Base *getBase() {return this;}
};

class pub_prot_Derv : public prot_Derv {
   Base *getBase() {return this;}
};

class pub_priv_Derv : public priv_Derv {
   //Base *getBase() {return this;}
};

1、对象类型不存在类型转换

Base b;
pub_Derv pd;
b = pd;  // 是调用了Base的拷贝构造函数,而不是类型转换
pd = b;  // 调用pub_Derv的拷贝赋值运算符,但是Base类型不能转为pub_Derv类型的引用,这个语句会报错。

2、子类的指针或引用转为父类的指针或引用:子类--->父类

不是子类的指针或引用就能转为父类的指针或引用,前提条件是子类的指针或引用在当前域(域内:类体类->成员函数和友元函数 域外:类体外)能够访问访问父类的public的成员,因为父类对象在域外就是能访问其public成员。

  • 子类对象在域外
Base *p;
p = new pub_Derv;     // 正确转换,Base的public成员在pub_Derv中还是public的,所以pub_Derv的域外对象能够访问Base的public成员。
p = new prot_Derv;    // 错误转换,Base的public成员在prot_Derv中还是protected的,所以prot_Derv的域外对象不能访问Base的public成员。
p = new priv_Derv;    // 错误转换,Base的public成员在priv_Derv中还是private的,所以priv_Derv的域外对象不能访问Base的public成员。
p = new pub_pub_Derv;   // 正确转换,Base的public成员在pub_pub_Derv中还是public的,所以pub_pub_Derv的域外对象能够访问Base的public成员。
p = new pub_prot_Derv;  // 错误转换,Base的public成员在pub_prot_Derv中是protected的,所以pub_prot_Derv的域外对象不能访问Base的public成员。
p = new pub_priv_Derv;  // 错误转换,Base的public成员在pub_priv_Derv中是inaccessible的,所以pub_priv_Derv的域外对象不能访问Base的public成员。
  • 子类对象在域内
class pub_prot_Derv : public prot_Derv {
    // 正确转换,Base的public成员在pub_prot_Derv中是protected的,pub_prot_Derv的域内对象能够访问pub_prot_Derv的protected成员,
    // 所以pub_prot_Derv的域内对象能转换为Base对象。
    Base *getBase() {return this;} 
};

class pub_priv_Derv : public priv_Derv {
    // 错误转换,因为Base的public成员在priv_Derv中是private的,到了pub_priv_Derv就变成inaccessible的了,也就是说在pub_priv_Derv的域内
    // 也访问不了Base的public成员,所以pub_priv_Derv的域内对象不能转换为Base对象。
    Base *getBase() {return this;} 
};

3、父类指针或引用转为子类指针或引用:父类--->子类

Base *pb = new pub_Derv;
// 父类指针或引用本来就是指向子类对象,则可以通过强制类型转换进行父类到子类的转换,来屏蔽编译器的检测,
// 如果父类不是指向之类,而这样转换就很危险了。
pub_Derv pb2 = static_case<pub_Derv>(pb); 
posted @ 2021-12-02 23:22  下夕阳  阅读(2835)  评论(0编辑  收藏  举报