高端网站开发制作,flash网站作品欣赏,兰州网站建设多少钱,全自动引流推广软件 ✨前言✨ #x1f393;作者#xff1a;【 教主 】 #x1f4dc;文章推荐#xff1a; ☕博主水平有限#xff0c;如有错误#xff0c;恳请斧正。 #x1f4cc;机会总是留给有准备的人#xff0c;越努力#xff0c;越幸运#xff01; #x1f4a6;导航助手#x1… ✨前言✨ 作者【 教主 】 文章推荐 ☕博主水平有限如有错误恳请斧正。 机会总是留给有准备的人越努力越幸运 导航助手 什么是继承
继承是面向对象编程的三大特性之一是一种使代码得以复用的重要手段。使程序员可以在已有类的基础上进行拓展产生新的类已有类称为基类或父类新的类称为派生类或子类。
class Person
{
public:int age;string name;
};
class Student:public Person
{
public:int stuId;
};
继承的书写格式class 子类继承方式 父类
继承方式
public继承protected继承private继承
不同的继承方式在子类中的基类成员访问方式不同 总结 无论是哪种继承方式基类中的私有成员在子类中都是不可以访问的继承方式可以省略class默认继承是privatestruct默认继承是public但是为了代码的可读性建议写上继承方式一般都用public继承很少用其他两种方式继承
继承中的一些问题
切片
将子类对象赋值给父类对象/父类指针/父类引用就叫做切片顾名思义就是把子类中继承自父类的那一部分切出来赋值。
赋值完成后父类对象/父类指针/父类引用就只保留属于父类的那一部分
注意子类可以赋值给父类但是父类不能赋值给子类
继承的隐藏规则
规则如果父类与子类定义了同名变量或者同名函数那么子类在访问该变量或者函数时默认访问的是子类的而不是父类的如果要访问子类对象中继承来自父类的同名变量或者同名函数需要指定父类作用域。
举例类A有成员变量num成员函数print()类B继承类A类B定义同名变量num同名函数print()
代码如下
class A
{
public:int num;void print(){cout A::print() endl;}
};class B :public A
{
public:int num;void print(){cout B::print() endl;}
};int main()
{B b;//访问b中的变量num与print()b.num 10;cout b.num endl;b.print();//访问b中继承自A的变量num与print()b.A::num 20;cout b.A::num endl;b.A::print();return 0;
} 代码运行结果如下 注意这不是函数重载函数重载是在同一个作用域内函数名相同而参数不同这是隐藏是两个作用域。
默认成员函数
子类构造函数必须调用父类构造函数来初始化继承自父类的部分如果父类没有默认构造必须在子类构造函数初始化列表中显式调用父类构造来初始化拷贝构造与赋值重载也必须调用父类的来完成析构函数中子类完成清理工作后会自动调用父类析构不用显式调用父类析构
构造与析构顺序
构造父类先构造子类后构造
析构子类先析构父类后析构
举例代码如下
class A
{
public:A(){cout A() endl;}~A(){cout ~A() endl;}
};
class B :public A
{
public:B(){cout B() endl;}~B(){cout ~B() endl;}
};
int main()
{B b;return 0;
}
运行结果如下 静态成员
整个继承体系中只有一个static成员无论怎样继承只有一份。
菱形继承
什么是菱形继承
菱形继承也叫做钻石继承因为形状像菱形所以叫做菱形继承。 class A
{
public:int a;
};class B1 :public A
{};class B2 :public A
{};class C :public B1, B2
{};
有一类AA中有一个数据成员a类B1和类B2公有继承类A所以B1和B2中都有数据成员a类C公有继承B1和B2这时候类C中就有两份数据成员a一份来自B1一份来自B2这就造成了数据冗余。并且在访问C对象访问a时会造成二义性。
如何解决菱形继承
解决菱形继承需要使用虚继承。B1和B2虚继承A继承时加上关键字virtual代码如下。
class A
{
public:int a;
};class B1 :virtual public A
{};class B2 :virtual public A
{};class C :public B1, B2
{};
这样即可解决菱形继承的代码冗余以及二义性问题。无论是指定作用域访问还是默认访问访问的都是同一个变量a。
可能有人问为什么C要设计这么复杂的继承机制不像java一样不支持多继承不就解决这样复杂的问题了吗
在我的博客深度剖析菱形继承 中深度解析了菱形继承的细节问题感兴趣的朋友可以自行阅读。
C作为比较早期的面向对象的编程语言属于是摸着石头过河所以有缺陷也是可以理解的。 欢迎关注码字不易希望多多点赞、收藏哦抱拳了。