c++继承知识总结
来源:互联网 发布:黑龙江科技大学网络课 编辑:程序博客网 时间:2024/06/08 05:09
c++继承相关知识总结
一 继承关系:public protected private
不矫情 直接贴代码 举例
代码主要从:
a. 基类成员对其对象的可见性: 只有public成员可以访问
b. 基类成员对派生类的可见性:
c. 基类成员对派生类对象的可见性:
a. 基类成员对其对象的可见性: 只有public成员可以访问
b. 基类成员对派生类的可见性:
c. 基类成员对派生类对象的可见性:
父类(基类)
class Base{public:Base(){_pri = 1;_pro = 2;_pub = 3;}private:int _pri;protected:int _pro;public:int _pub;};
(1)public 继承方式
class Derived1 :public Base{public:Derived1(){_d1_pri = 4;_d1_pro = 5;_d1_pub = 6;}void showd(){_pub = 0; // 仍为public成员_pro = 2; // 仍为protected成员//_pri = 3; // 父类私有成员对子类 不可见}private:int _d1_pri;protected:int _d1_pro;public:int _d1_pub;};void TestPublic(){Base b;b._pub = 1;//b._pro = 2; // 父类对象不可访问父类保护成员//b._pri = 3; // 父类对象不可访问父类私有成员Derived1 d1;d1._pub = 1; // 子类对象可以访问父类公有成员//d1._pro = 2; //子类对象不可访问父类保护成员//d1._pri = 3; // 子类对象不可访问父类私有成员d1._d1_pub = 4;}(2) protected继承
// protected 保护继承class Derived2 :protected Base{public:Derived2(){_d2_pri = 4;_d2_pro = 5;_d2_pub = 6;}void showd(){_pub = 1; // 变为子类的protected成员_pro = 2; // 仍为protected成员//_pri = 3; // 父类私有成员对子类不可见}private:int _d2_pri;protected:int _d2_pro;public:int _d2_pub;};void TestProtected(){Base b;b._pub = 1;//b._pro = 2; // 父类对象不可访问父类保护成员//b._pri = 3; // 父类对象不可访问父类私有成员Derived2 d2;//d2._pub = 1; // 父类的public成员权限被修改为protected,子类对象不可访问//d2._pro = 2; //子类对象不可访问父类保护成员//d2._pri = 3; // 子类对象不可访问父类私有成员d2._d2_pub = 4;}(3)私有继承
// private私有继承class Derived3 :private Base{public:Derived3(){_d3_pri = 4;_d3_pro = 5;_d3_pub = 6;}void showd(){_pub = 1; // 变为子类的privite成员_pro = 2; // 变为子类的privite成员//_pri = 3; // 父类私有成员对子类不可见}private:int _d3_pri;protected:int _d3_pro;public:int _d3_pub;};void TestPrivate(){Base b;b._pub = 1;//b._pro = 2; // 父类对象不可访问父类保护成员//b._pri = 3; // 父类对象不可访问父类私有成员Derived3 d3;//d3._pub = 1; // 父类的public成员权限被修改为private,子类对象不可访问//d3._pro = 2; // 父类的protected成员权限被修改为private,子类对象不可访问//d3._pri = 3; // 子类对象不可访问父类私有成员d3._d3_pub = 4;}总结一下继承方式
1 基类的private成员在派生类中是不能被访问的,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected。可以看出保护成员限定符是因继承才出现的。
2不管是哪种继承方式,在派生类内部都可以访问基类的公有成员和保护成员,基类的私有成员存在但是在子类中不可见(不能访问)。
3 使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式。
二 派生类(子类)的默认成员函数
1 继承关系中构造函数和析构函数
(1)继承关系中的构造函数和析构函数的调用
构造函数的调用顺序 :Derived d;
析构函数的调用顺序 :
说明:
a 、基类没有缺省构造函数,派生类必须要在初始化列表中显式给出基类名和参数列表。
b、基类没有定义构造函数,则派生类也可以不用定义,全部使用缺省构造函数。
c、基类定义了带有形参表构造函数,派生类就一定定义构造函数 (无参或者带参)
代码举例
<span style="font-size:18px;">class A{public: A(){cout<<"this is A::A()"<<endl;} A(int b){cout<<"this is A::A(int b): the value of b is: "<<b<<endl;} A(double b){cout<<"this is A::A(double b) the value of b is: "<<b<<endl;}};class B:public A{public: B():A(){} //调用基类 A 默认构造函数 B(int b):A(b){} //调用基类 A 的 A::A(int b) 构造函数 B(double b):A(b){} //调用基类 A 的 A::A(double b) 构造函数};void main(){ B b0,b1(5),b2(10.5);//产生三个实例,分别调用不同的基类构造函数 system("pause");}/***********************************调用 func 函数的输出结果:this is A::A()this is A::A(int b): the value of b is: 5this is A::A(double b) the value of b is: 10.5***********************************/</span>
2继承体系中的作用域
2.a. 在继承体系中基类和派生类是两个不同作用域。
2.b. 子类和父类中有同名成员,子类成员将屏蔽父类对成员的直接访问。(在子类成员函数中,可以使用 基类::基 类 成员 访问)--隐藏 --重定义
2.c. 注意在实际中在继承体系里面最好不要定义同名的成员。
2.c. 注意在实际中在继承体系里面最好不要定义同名的成员。
3继承与转换--赋值兼容规则--public继承
记忆法: 大的可以赋值给小的
注意:只有public继承才有
3.a. 子类对象可以赋值给父类对象(切割/切片)
3.b. 父类对象不能赋值给子类对象
3.c. 父类的指针/引用可以指向子类对象
3.d. 子类的指针/引用不能指向父类对象(可以通过强制类型转换完成)
3.b. 父类对象不能赋值给子类对象
3.c. 父类的指针/引用可以指向子类对象
3.d. 子类的指针/引用不能指向父类对象(可以通过强制类型转换完成)
4 友元与继承
友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员
注意下面的例子:<<运算符的重载函数 不能说明友元关系可以继承
<span style="font-size:18px;">class Base{public:friend ostream& operator<<(ostream& _cout,Base &base){_cout << base._pri << endl;return _cout;}private:int _pri;};class Derived :public Base{};void TestBase(){Base b;cout << b; Derived d;cout << d; // 参数发生类型转换 派生类对象赋值给基类对象}</span>
三 继承方式 单继承 多继承( 菱形继承)
单继承
class A{public:A(){_a = 1;}public:int _a;};class B: public A{public:B(){_b = 2;}public:int _b;};// 创建一个B 类的对象b 查看内存 0x004FFAD8 00000001 00000002
单继承的数据模型
多继承(普通)
class A{public:A(int a):_a(a){}public:int _a;};class B{public:B(int b):_b(b){}public:int _b;<strong></strong>};class C:public A,public B{public:C(int a,int b,int c): B(a) // 不是按初始化顺序来初始化派生类的, A(b) // 而是按继承顺序 public A public B 来调用其构造函数, _c(c){}public:int _c;};//创建一个C 类的对象c 查看内存 0x0023F904 00000002 00000001 00000003数据模型:
多继承中的菱形继承(也叫钻石继承)
class A{public:A(int a = 0){}public:int _a;};class B1:public A{public:B1(int b):_b1(b){}public:int _b1;};class B2 :public A{public:B2(int b2):_b2(b2){}public:int _b2;};class C :public B1,public B2{public:C(int b1,int b2,int c): B1(b1), B2(b2), _c(c){}public:int _c;};void testD(){C c(1,2,3);c.B1::_a = 4; // 必须指定_a的作用域 不然不知道_a属于B1 还是B2c.B2::_a = 5; // 因此这样就存在二义性 }
数据模型
由于存在二义性 因此引入虚继承
虚继承:
class A{public:A(int a = 0){_a = a;}public:int _a;};class B1:virtual public A{public:B1(int b):_b1(b){}public:int _b1;};class B2 :virtual public A{public:B2(int b2):_b2(b2){}public:int _b2;};class C :public B1,public B2{public:C(int b1,int b2,int c): B1(b1), B2(b2), _c(c){}public:int _c;};void testD(){cout << sizeof(C) << endl; // 24 B1的大小(8)+B2的大小(8)+C的成员变量(4) =20 多了4个字节C c(1,2,3);//c._a = 1; // 这样就不用作用域限定来指定_a所属}数据模型:
关于 继承这块 就给大家分享这么多了,欢迎大家指错
3 0
- Java知识总结-继承
- java继承知识总结
- java继承知识总结
- c++继承知识总结
- 继承体系知识总结
- Java继承知识总结
- 【C++】继承总结
- C一些知识总结
- C一些知识总结
- keil c 知识总结
- c语言 知识总结
- keil c 知识总结
- C Assignment2 知识总结
- C语言知识总结
- C高级知识总结
- C语言知识总结
- C语言知识总结
- C语言知识总结
- 为Linux配置apt-get的更新源
- 推荐系统-小入个门
- hdu1007 Quoit Design(最近点对模板题)
- MongoDB数据库的基本操作(二)
- C++_STL_algorithm(算法)
- c++继承知识总结
- 栈的应用1——十进制转换任何进制
- C语言开发流程
- 微小宝中实际支出是如何计算的?
- 求1-100之间9的个数
- 内核启动流程2——C语言部分
- ExcuteScalar的使用
- 栈的应用2--括号匹配问题
- servlet和jsp的转发与重定向代码以及区别