栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++高级编程【继承】

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++高级编程【继承】

文章目录
  • 类内成员的权限
  • 继承的作用
  • 继承方式
  • 继承中的构造和析构顺序
  • 初始化列表在继承中的作用
  • 继承中同名成员处理
  • 继承和组合情况下构造和析构调用顺序
  • 不能继承的函数
  • 多继承
  • 菱形继承的问题
  • 虚继承
  • 虚基类初始化问题

类内成员的权限
publicprivateprotected
类内、类外、子类都可以访问类内可以访问,类外不能访问,子类不能访问类内可以访问,类外不能访问,子类可以访问

类内部的成员权限决定了子类能否被继承
只有public 和protected 权限的成员才能被子类继承

C++ 最重要的特征是代码重用,通过继承机制可以利用已有的数据类型来定义新的数据类型,新的类不仅拥有旧类的成员,还拥有新定义的成员

继承的作用
  • 复用已有类的数据、函数,减少冗余代码。

    将公共的函数写在基类中,通过继承来实现复用

  • 修改已有类的功能,而不修改原类。

    如果类内部的函数不能满足需求时,需要修改该函数的功能。
    修改源代码的代价很大,所以应该使用重定义该函数来实现我们自己的需求
    (当子类重定义父类的函数时,父类的函数会被隐藏)

  • 扩展已有类的功能,而不修改原类。
  • 为实现强大的多态机制做支撑。
继承方式
  • 继承的方式决定了被继承下来的成员在子类中的权限
publicprivateprotected
基类什么权限,继承下来就是什么权限继承下来的成员在子类中全部为private权限继承下来的成员在子类中全部为protected权限
继承中的构造和析构顺序
class Base
{
public:
	Base()
	{
		cout<<"base构造函数"<
		cout<<"base析构函数"<
public:
	Derived()
	{
		cout<<"Derived构造函数"<
		cout<<"Derived析构函数"<
		Derived der;
}

创建对象时,首先调用父类的构造,在调用子类的构造
销毁对象时,首先调用子类的析构,在调用父类的析构

初始化列表在继承中的作用

子类初始化时,编译器默认调用父类的无参构造,当父类没有提供无参构造时,
需要使用初始化列表指定调用父类的哪一个构造函数

class Base
{
public:
	Base(int a)
	{
		cout<<"base构造函数"<}
}

class Derived : public Base
{
public:
	Derived(int num) :Base(num)
	{
		cout<<"Derived构造函数"<} 
}


void test()
{
	Derived der(10);
}	
继承中同名成员处理
  • 当子类成员和父类成员同名,父类同名成员会被隐藏。
  • 子类默认访问子类的成员。
  • 子类内部通过 类名::成员 的方式访问父类同名成员。
  • 任何时候重新定义基类中的一个重载函数,在新类中所有的其他版本将被自动隐藏。
继承和组合情况下构造和析构调用顺序

当其他类作为当前类的对象成员,这种关系为组合关系
初始化顺序

  1. 先调用父类构造函数。
  2. 在调用对象成员构造函数,按照定义顺序。
  3. 最后调用子类构造函数。
  4. 析构函数调用与构造函数调用相反。
不能继承的函数
  1. 私有权限的函数。
  2. 构造函数。
  3. 析构函数。
  4. 赋值运算符函数。

构造函数和析构函数用来处理对象的创建和析构操作,构造和析构函数只知道对它们的特定层次的对象做什么,也就是说构造函数和析构函数不能被继承,必须为每一个特定的派生类分别创建。

operator=也不能被继承,因为它完成类似构造函数的行为。也就是说尽管我们知道如何由=右边的对象如何初始化=左边的对象的所有成员,但是这个并不意味着对其派生类依然有效

多继承
  • 多继承可以复用多个类的代码
  • 多继承容易出现二义性的问题
  • 二义性只能通过类名访问来解决(应该避免二义性)
菱形继承的问题

二义性问题。
子类中存在多份基类数据。
使用虚继承可以解决菱形继承的问题

虚继承

当子类使用虚继承后,父类就变成了虚基类
如果一个类时虚基类,该类的数据在所有的子类中只会出现一份
虚继承主要是解决菱形继承的问题

语法

class Animal
{
public:
    Animal()
    {
        cout << "Animal 构造函数" << endl;
    }

    ~Animal()
    {
    }
public:
    int m_animal;
};
//虚继承
class Demo : virtual public Animal
{
public:
	int m_demo;
}

虚基类初始化问题

当使用虚继承时,虚基类是被共享的,也就是在继承体系中无论被继承多少次,对象内存模型中均只会出现一个虚基类的子对象。

C++ 标准中要求在每一次继承子类中都必须书写初始化语句(因为每一次继承子类可能都会用来定义对象),但是虚基类的初始化是由最后的子类完成,其他的初始化语句都不会调用。

虚继承总结

当发生虚继承时,子类没有将基类的数据继承到本类中,编译器会在子类中安插vbptr指针
vbptr 指针指向保存着基类数据偏移量的表,通过该表找到基类数据。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/921022.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号