c/c++ 继承与多态 由子类向父类的转换规则
程序员文章站
2024-01-26 22:10:58
问题1:子类B可以有3种方式(public, protected, private)继承父类A,用哪种方式继承,用户代码才能把子类B的对象转换成父类A的对象呢? 只用当子类B以public方式继承父类A后,在用户代码里,才能把子类B的对象转换成父类A的对象。 原因如下: 下面例子的类Pro_derv ......
问题1:子类b可以有3种方式(public, protected, private)继承父类a,用哪种方式继承,用户代码才能把子类b的对象转换成父类a的对象呢?
只用当子类b以public方式继承父类a后,在用户代码里,才能把子类b的对象转换成父类a的对象。
原因如下:
- 下面例子的类pro_derv和类pri_derv,分别是以protected和 private的方式继承了base,所以在类pro_derv和类pri_derv对象里,原来在base类里的成员pub_mem()已经不是public的属性了,而分别是protected和 private的属性了,protected和 private属性的成员对于用户程序来说是不可访问的。
- 当创建了pro_derv和类pri_derv的对象后,成员pub_mem()已经是分别是protected和 private的属性了。所以类pro_derv和类pri_derv的用户程序是不可以访问protected或者 private属性的成员pub_mem()的。
- 当要把类pro_derv和类pri_derv的对象转换成父类base类的对象的时候,从类base的角度看,pub_mem()是public的成员,所以类base的用户程序是可以访问pub_mem()的,但是从类pro_derv和类pri_derv的角度看,pub_mem()已经不是public的成员了,所以类pro_derv和类pri_derv的用户程序是不可以访问成员pub_mem()的。这时,编译器就很困惑这个矛盾了,所以编译器干脆就不让你编译通过。。。
class base{ public: void pub_mem(); protected: int prot_mem; private: char pri_mem; }; class pub_derv : public base{ int f(){ pub_mem(); return prot_mem; } //char g(){return pri_mem;}//error }; class pro_derv : protected base{ int f(){ pub_mem(); return prot_mem; } //char g(){return pri_mem;}//error }; class pri_derv : private base{ int f(){ pub_mem(); return prot_mem; } }; int main(){ pub_derv pub; pro_derv pro; pri_derv pri; base& b1 = pub; base& b2 = pro;//error base& b3 = pri;//error }
问题2:子类b可以有3种方式(public, protected, private)继承父类a,用哪种方式继承,在子类b的成员函数和子类b的友元(非用户代码)里才能把子类b的对象转换成父类a的对象呢?
不论子类b以何种方式继承父类a,在子类b的成员函数和子类b的友元里(非用户代码),都能把子类b的对象转换成父类a的对象。
原因如下:
- 不论子类b以何种方式继承父类a,在子类b的成员函数和子类b的友元(非用户代码)里,父类a的所以成员的属性是不发生变化的,所以转化后,还是可以用父类a的对象,访问父类a的public成员。
class base{ public: void pub_mem(); protected: int prot_mem; private: char pri_mem; }; class pub_derv : public base{ int f(){ pub_mem(); return prot_mem; } //char g(){return pri_mem;}//error }; class pro_derv : protected base{ friend void pro_fri(pro_derv&); int f(){ base& b = *this;//不论子类b以何种方式继承父类a,在子类b的成员函数和子类b的友元(非用户代码)里,都能把子类b的对象转换成父类a的对象。 pub_mem(); return prot_mem; } //char g(){return pri_mem;}//error }; class pri_derv : private base{ friend void pri_fri(pri_derv&); int f(){ base& b = *this;//不论子类b以何种方式继承父类a,在子类b的成员函数和子类b的友元(非用户代码)里,都能把子类b的对象转换成父类a的对象。 pub_mem(); return prot_mem; } }; void pro_fri(pro_derv& pro){ base& b = pro;//不论子类b以何种方式继承父类a,在子类b的成员函数和子类b的友元(非用户代码)里,都能把子类b的对象转换成父类a的对象。 } void pri_fri(pri_derv& pro){ base& b = pro;//不论子类b以何种方式继承父类a,在子类b的成员函数和子类b的友元(非用户代码)里,都能把子类b的对象转换成父类a的对象。 } int main(){ pub_derv pub; pro_derv pro; pri_derv pri; base& b1 = pub; //base& b2 = pro; //base& b3 = pri; }
问题3:子类b可以有3种方式(public, protected, private)继承父类a,用哪种方式继承,子类b的子类c的成员函数和子类b的子类c的友元里,才能把子类b的对象转换成父类a的对象呢?
只用当子类b以public或者protected方式继承父类a后,在子类b的子类c的成员函数和子类b的子类c的友元里,才能把子类b的对象转换成父类a的对象。
class base{ public: void pub_mem(); protected: int prot_mem; private: char pri_mem; }; class pub_derv : public base{ int f(){ pub_mem(); return prot_mem; } //char g(){return pri_mem;}//error }; class pro_derv : protected base{ int f(){ pub_mem(); return prot_mem; } //char g(){return pri_mem;}//error }; class pri_derv : private base{ int f(){ pub_mem(); return prot_mem; } }; class pub_pub_derv : private pub_derv{ friend void pubpubfri(pub_pub_derv&); int f(){ base& b = *this;//只用当子类b以public或者protected方式继承父类a后,在子类b的子类c的成员函数和子类b的子类c的友元里,才能把子类b的对象转换成父类a的对象 pub_mem(); return prot_mem; } //char g(){return pri_mem;}//error }; class pro_pro_derv : private pro_derv{ friend void proprofri(pro_derv&); int f(){ base& b = *this;//只用当子类b以public或者protected方式继承父类a后,在子类b的子类c的成员函数和子类b的子类c的友元里,才能把子类b的对象转换成父类a的对象 pub_mem(); return prot_mem; } //char g(){return pri_mem;}//error }; class pri_pri_derv : private pri_derv{ friend void priprifri(pri_derv&); int f(){ //base* b = *this;//error,只用当子类b以public或者protected方式继承父类a后,在子类b的子类c的成员函数和子类b的子类c的友元里,才能把子类b的对象转换成父类a的对象 //pub_mem(); //return prot_mem; } }; void pubpubfri(pub_derv& pd){ base& b = pd;//只用当子类b以public或者protected方式继承父类a后,在子类b的子类c的成员函数和子类b的子类c的友元里,才能把子类b的对象转换成父类a的对象 } void proprofri(pro_derv& pd){ base& b = pd;//只用当子类b以public或者protected方式继承父类a后,在子类b的子类c的成员函数和子类b的子类c的友元里,才能把子类b的对象转换成父类a的对象 } void priprifri(pri_derv& pd){ //base& b = pd;//error,只用当子类b以public或者protected方式继承父类a后,在子类b的子类c的成员函数和子类b的子类c的友元里,才能把子类b的对象转换成父类a的对象 } int main(){ pub_derv pub; pro_derv pro; pri_derv pri; base& b1 = pub; //base& b2 = pro; //base& b3 = pri; }