C++之继承篇
来源:互联网 发布:just do it 乔丹 编辑:程序博客网 时间:2024/05/22 11:52
1.继承权限
注:protected和private的区别:
protected:在派生类中可以访问,类外不可访问
private:派生类和类外均不可访问
2.继承定义格式
3.同名隐藏
定义:基类,派生类某一个成员变量同名,或者某一个成员函数同名(只要函数名一样,不管参数列表,返回值是否一样),通过派生类调用该成员变量或成员函数时,只会调用派生类的,基类的看不到,这种现象称为同名隐藏。
#include <iostream>#include <windows.h>using namespace std;class Base{public:int _pub; void Fun1(){cout<<"Base::void Fun1()"<<endl;} void Fun2(int){cout<<"Base::void Fun2(int)"<<endl;}int Fun3(){cout<<"Base::int Fun3()"<<endl;return 0;}};class Derived:public Base{public:int _pub; void Fun1(){cout<<"Derived::Fun"<<endl;} void Fun2()//与Base中Fun2相比不带参数{cout<<"Derived::void Fun2(int)"<<endl;}void Fun3()//与Base中Fun3相比返回值不同{cout<<"Derived::void Fun3()"<<endl;}};int main(){ Derived d; Base b; b._pub=1; d._pub=2; cout<<d._pub<<endl; d.Fun1(); d.Fun2(); d.Fun3(); system("pause"); return 0;}
结果:
4.对象模型
测试代码:
#include <iostream>#include <windows.h>using namespace std;class Base{public:int _pub;int _pro;int _pri;};class Derived:public Base{public:int _pub1;};int main(){ Derived d; Base b; b._pub=1; b._pro=2; b._pri=3; d._pub1=4; d._pub=5; d._pro=6; d._pri=7; system("pause"); return 0;}
总结:基类的对象模型是按照声明次序的。派生类是先是基类的,然后是自己的(按照声明顺序排列)。
5.派生类对象
class Base{public:Base(){cout<<"Base::Base()"<<endl;}~Base(){cout<<"Base::~Base()"<<endl;}private:int _pub;int _pro;int _pri;};class Derived:public Base{public: Derived() { cout<<"Derived::Derived()"<<endl; } ~Derived() { cout<<"Derived::~Derived()"<<endl; }private:int _pub1;};
定义一个派生类对象
Derived d;
d的调用顺序为:Derived()->~Derived()
实际执行顺序:Base() ->Derived()-> ~Derived()->~Base()
小结:
(1)基类有缺省构造函数,派生类无构造函数,系统会给派生类自动合成
(2)基类无构造函数,派生类无构造函数,系统不会给基类,派生类自动合成
(3)基类构造函数有参数,派生类必须定义构造函数,并在初始化列表显示调用基类的构造函数
6.赋值兼容规则-----public继承
#include <iostream>#include <windows.h>using namespace std;class Base{public:int _b;};class Derived:public Base{public: int _d;};int main(){ Base b; Derived d; b=d; d=b; Base &b1=d; Base *p=&d; Derived &d=b; Derived * p1=&b; }小结:
(1)子类对象可以赋值给父类对象。原理就像是切片/切割一样。
(2)父类对象不能赋值给子类对象。
(3)父类的指针/引用可以指向子类对象。
(4)子类的指针/引用不能指向父类对象。
7.友元函数&Static&继承
友元函数属于类外函数,所以不能继承。
static修饰的成员可以继承,但是,无论多少派生类,只有一份Static修饰的成员。
8.多继承
如: 有class A,class B,
class C:public A,public B
C类的父类有两个,便成C类为多继承。
注:继承多个类时,每个类的继承权限不能省略,否则,class默认的继承权限是private。
9.菱形继承
#include <iostream>#include <windows.h>using namespace std;class B{public:int _b;};class C1:public B{public:int _c1;};class C2:public B{public:int _c2;};class D:public C1,public C2{public:int _d;};int main(){ D d; d.C1::_b; d._c1; d.C2::_b; d._c2; d._d ; system("pause"); return 0;}
注:D类对象访问_b时,需要加上作用域,不然会产生二义性。因为C1,C2类各有一个_b,D类对象访问时,不知要访问哪个。10.虚继承---解决菱形继承的二义性和数据冗余的问题
继承权限前面加上virtual关键字。
例如:
class A{public:int _a;};class B:virtual public A{public:int _b;};int main(){B b;b._a=1;b._b=2; return 0;}小结:
(1)虚继承中,在程序编译时,偏移量的表格已经生成。在调用构造函数时,只是将地址存入。
(2)虚继承中,A类若是无构造函数,B类自动合成构造函数。(将指向偏移量的地址存入对象的前四个字节)。
(3)虚继承与普通继承的区别在于,调用构造函数前,先PUSH 1,以此来判断是否为虚继承,若是,便执行(2)中所说。
(4)虚继承中,基类的成员变量只存在一份,所以当派生类对象调用基类对象时,不会存在二义性问题,因此,虚继承可以解决菱形继承中的二义性问题和数据冗余的问题。
用虚继承解决菱形继承中二义性问题:
#include <iostream>#include <windows.h>using namespace std;class B{public:int _b;};class C1:virtual public B{public:int _c1;};class C2:virtual public B{public:int _c2;};class D:public C1,public C2{public:int _d;};int main(){ D d; d._b=1; d._c1=2; d._c2=3; d._d =4; system("pause"); return 0;}
注意: 是C1和C2虚继承B类,所以只在这前面加virtual关键词。
下面举一个在不同位置加VIRTUAL关键词,看会引起什么不同
#include <iostream>#include <windows.h>using namespace std;class B{public:int _b;};class C1: public B{public:int _c1;};class C2: public B{public:int _c2;};class D:virtual public C1,virtual public C2{public:int _d;};int main(){ D d; d.C1::_b=1; d._c1=2; d.C2::_b=5; d._c2=3; d._d =4; system("pause"); return 0;}
上述的这种情况,并没有解决菱形二义性的问题。
1 0
- object-c之继承
- Object-C之继承
- 【C++】:C++之继承
- objective-c之继承
- C ++之继承浅析
- 初识Objecive-C 之 继承
- 【C#】面向对象之继承
- 【C#】C#OOP编程之继承性
- C++(继承篇)
- 【C++】继承和多态之——菱形继承
- c与面象对象之继承
- IOS之Objective-C 的“多继承”
- IOS之Objective-C 的“多继承”
- Objective-C语法之继承、封装、多态
- Object-C: 学习实例之继承
- 用C实现面向对象之继承
- 【iOS开发之Objective-C】继承
- object -c笔记之导入和继承
- React Native填坑之旅 -- 使用iOS原生视图(高德地图)
- MATLAB学习(三)字符串、元胞&构架数组
- 微信js sdk invalid signature签名错误
- echarts图形的弹窗修改方法
- Servlet
- C++之继承篇
- leetcode124~Binary Tree Maximum Path Sum Add to List
- JavaSript模块化
- 【vue2.0】Cannot read property 'matched' of undefined
- Ubuntu下批量更改图片大小
- Git使用错误收集:-ssh agent失败 错误代码-1
- java文件操作之递归获取视频文件
- 深入理解 CSS 时序函数
- 数据库版本控制插件Flyway Q&A