在本文中,我们将一起深入探讨C++继承的奥秘,从基础概念到高级应用,逐步揭开它的神秘面纱 C++继承允许我们定义一个基类(或称为父类),并从这个基类中派生出新的类(称为派生类、子类)。...继承中的作用域 关于作用域的注意事项: 在继承体系中基类和派生类都有独立的作用域。 子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义。...派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。...因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序 派生类对象初始化先调用基类构造再调派生类构造 派生类对象析构清理先调用派生类析构再调基类的析构 因为后续一些场景析构函数需要构成重写,重写的条件之一是函数名相同...那么编译器会对析构函数名进行特殊处理,处理成destrutor(),所以父类析构函数不加virtual的情况下,子类析构函数和父类析构函数构成隐藏关系 综上所述:关于基类和子类的调用顺序,一般情况都是先父后子
继承的概念及定义 1.1 继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。...派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。 派生类对象初始化先调用基类构造再调派生类构造。...派生类对象析构清理先调用派生类析构再调基类的析构。 因为后续一些场景析构函数需要构成重写,重写的条件之一是函数名相同(后面会提)。...那么编译器会对析构函数名进行特殊处理,处理成destrutor(),所以父类析构函数不加virtual的情况下,子类析构函数和父类析构函数构成隐藏关系。...赋值构造 如果没有指明作用域,它和父类是同名函数,会构成隐藏,优先调用自己的,就会死循环。
虚函数的重写(也可以叫覆盖): 派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型、函数名字、参数列表完全相同),称子类的虚函数重写了基类的虚函数。...,对于自定义类型delete会做的是: 1. 在要释放的对象空间上执行析构函数,完成对象中资源的清理工作 2....但是: 重写不是要求基类和派生类的虚函数名字一样吗,可是它们两个的析构函数名字并不一样啊。...只有派生类Student的析构函数重写了Person的析构函数,delete对象调用析构函数,才能构成多态,才能保证p1和p2指向的对象正确的调用析构函数。...你可以把它看作是一个规范,告诉其他类应该有哪些方法,并且如何使用这些方法。 举个例子来说明抽象类的概念: 假设我们有一个抽象类叫做"动物",其中有一个纯虚函数"发出声音"。
人要工作,人派生出多个子类后,一个作家工作就是写文章,一个程序员工作却是写代码。工作的执行者不同,工作的内容也不同。 在类中成员函数前面加一个virtual,这个函数就变成了虚函数。...当子类child继承base的时候,创建一个base类的指针,让它 指向子类对象,这时候用基类指针调用print(),此时会自动判断,然后调用子类中的函数, 如果基类不加virtual,基类指针就直接调用基类的...如果一个类中有虚函数,那么编译器会在类的开始位置设置一个虚函数指针,指向一个数组(每一个元素都是函数指针), 这个数组就是虚函数表,它存储着每个虚函数的地址。...也可以看这段话: 基类指针可以指向派生类的对象(多态性),如果删除该指针delete []p; 就会调用该指针指向的派生类析构函数,而派生类的析构函数又自动调用 基类的析构函数,这样整个派生类的对象完全被释放...如果析构函数不被声明成虚函数,则编译器实施静态绑定, 在删除基类指针时,只会调用基类的析构函数而不调用派生类析构函数, 这样就会造成派生类对象析构不完全。所以,将析构函数 声明为虚函数是十分必要的。
再回头看看1.1中的例子,bar()作为A-B这个类层次的使用者,它并不知道这个类层次中有多少个类,每个类都叫什么,但是一样可以很好的工作,当有一个C类从A类派生出来后,bar()也不需要“知道”(修改...我所说的“标准”方式,也就是所谓的“VTABLE”机制。编译器发现一个类中有被声明为virtual的函数,就会为其搞一个虚函数表,也就是VTABLE。...不要把我实例化!纯虚函数用来规范派生类的行为,实际上就是所谓的“接口”。它告诉使用者,我的派生类都会有这个函数。 2.3 虚析构函数 析构函数也可以是虚的,甚至是纯虚的。...例如: class A { public: virtual ~A()=0; // 纯虚析构函数 }; 当一个类打算被用作其它类的基类时,它的析构函数必须是虚的。...3.2 构造函数和析构函数中的虚函数调用 一个类的虚函数在它自己的构造函数和析构函数中被调用的时候,它们就变成普通函数了,不“虚”了。也就是说不能在构造函数和析构函数中让自己“多态”。
继承(inheritance)机制是⾯向对象程序设计使代码可以复⽤的最重要的⼿段,它允许我们在保持原有类特性的基础上进⾏扩展,增加⽅法(成员函数)和属性(成员变量),这样产⽣新的类,称派⽣类。...基类和派生类中有同名函数时,派生类将屏蔽基类的同名函数的直接访问(这种情况叫做隐藏)(可以和后面多态中的覆盖/重写对比记忆,在多态章节的博客中详细讲解)。...派生类的析构函数会在被调用完成之后自动调用基类的析构函数清理基类成员;(这样才能保证派生类对象先清理派生类的那一部分成员,再清理基类成员这一顺序)。...派生类对象初始化先调用基类的构造函数,再调用派生类的构造函数。 派生类对象析构清理先调用派生类析构再调用基类的析构。...在多态的一些场景中,需要对析构函数构成重写,重写的条件是函数名相同(学习多态时了解);编译器会对析构函数名进行特殊处理,处理成destructor,所以基类的析构函数不加virtual 的情况下,派生类析构函数和基类析构函数构成隐藏
TObject是一个抽象类,它的派生类可以对TObject中的方法重载,包括对它的构造 Create 和析构 Destory的重载。...字段的声明类型于记录类型中字段的声明,类类 型中的方法又可以分为4类,分别是构造、析构、过程和函数。...一个类 可以没有也可以有多个构造和析构,构造和析构也可以继承。...Create和一个析构Destroy,实际上它们是分别继承了基类TGraphicControl 中的构造和析构,并重载的。...析构可以被声明为虚拟的,这样派生类就可以重载它的定义,甚至由多个析构的版本存在。
2) 一个派生类构造函数的执行顺序如下: ① 虚拟基类的构造函数(多个虚拟基类则按照继承的顺序执行构造函数)。 ② 基类的构造函数(多个普通基类也按照继承的顺序执行构造函数)。...,在销毁一个对象时,先调用子类的析构函数,然后再调用基类的析构函数。...2) 纯虚析构函数一定得定义,因为每一个派生类析构函数会被编译器加以扩张,以静态调用的方式调用其每一个虚基类以及上一层基类的析构函数。...中的构造和析构函数,从实验结果来看,语句1并没有体现,执行流程是先构造基类,所以先调用基类的构造函数,构造完成再执行A自己的构造函数,析构时也是调用基类的析构函数,也就是说构造和析构中调用虚函数并不能达到目的...weak_ptr 设计的目的是为配合 shared_ptr 而引入的一种智能指针来协助 shared_ptr 工作, 它只可以从一个 shared_ptr 或另一个 weak_ptr 对象构造, 它的构造和析构不会引起引用记数的增加或减少
在继承体系中基类和派生类都有独立的作用域。 2. 子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义。...派生类的析构函数会在被调用完成后 自动调用 基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。 5....派生类对象初始化 先调用基类构造再调派生类构造 。 6. 派生类对象析构清理 先调用派生类析构再调基类的析构 。 7....因为后续一些场景析构函数需要构成重写,重写的条件之一是函数名相同(这个我另一篇)。...那么编译器会对析构函数名进行特殊处理,处理成destrutor(),所以父类析构函数不加 virtual的情况下,子类析构函数和父类析构函数构成隐藏关系 六、继承与友元,静态成员 友元关系不能被继承
(基类与派生类析构函数的名字不同) 如果基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual关键字,都与基类的析构函数构成重写,虽然基类与派生类析构函数名字不同。...,如果基类的析构函数没有被声明为虚拟的(virtual),将会发生对象的不完全析构。...这意味着只有基类的析构代码会被执行,而派生类的析构逻辑不会调用,可能导致资源泄露或其他问题。...其中 p2 是一个基类 Person 类型的指针,指向一个 Student 对象),Student 的析构函数首先会被调用(子类),然后是 Person 的析构函数(基类) 因此,重写基类的虚拟析构函数确保了当通过基类指向派生类对象的指针进行...调用就可以看出存的是哪个函数 函数写好后,关键是我如何取到它的地址?
我在Person类和Student类都写了一个fun函数,这两个fun函数只有参数不同,那么是构成重载吗?不是,这两个函数构成隐藏 ,为什么呢?...那么编译器会对析构函数名进行特殊处理,处理成 destrutor() ,所以父类析构函数不加 virtual 的情况下,子类析构函数和父类析构函数构成隐藏关系。...Student的对象s时,调用了父类的构造和析构函数,这就说明了当派生类进行实例化时,会调用基类的构造函数来构造派生类中基类的成员。 ...那么拷贝构造和赋值重载怎么构造的呢?也是差不多的,使用基类的构造函数完成对基类成员的构造,然后使用赋值的切片,把基类的成员切过去构造。 那析构函数呢?...析构函数需要显示调用,而且还有一个特殊处理,就是析构要先析构派生类再析构基类。
---- 一、继承的概念和定义 1.概念 继承机制是面向对象程序设计使代码可以复用的有效手段。...4.析构函数 派生类额析构函数会在调用结束后自动调用基类的析构函数清理基类成员,确保先清理派生类的成员再清理基类的成员的析构顺序。 派生类对象析构先调用派生类析构函数再调用基类析构函数。...编译器会对析构函数的函数名进行特殊处理,即派生类和基类的析构函数名都会被处理为destructor()。因此派生类和基类的析构函数回构成隐藏。...七、菱形继承和菱形虚拟继承 1.单继承 一个派生类只有一个直接基类,这种称为单继承。 2.多继承 一个派生类有多个直接基类,这种情况称为多继承。...通过B和C中的两个指针分别指向的两张表,这两个指针叫做虚基表指针,这两张表叫做虚基表。虚基表中存放着A成员偏移量。(虚基表,实际上是一个数组)通过偏移量可以找到下面的A。
因为纯虚函数是不能被调用的,包含纯虚函数的类是无法建立对象的。 抽象类的作用是作为一个类族的共同基类,或者说,为一个类族提供一个公共接口。 3.为什么有的类的析构函数需要设为virtual?...是否每个类的析构函数都要设置成virtual?是否可以将析构函数设置成内联函数。 这样做是为了当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用。...所以,只有当一个类被用来作为基类的时候,才把析构函数写成虚函数。 可以。 4.析构函数是否可以是纯虚函数? 可以,当需要定义一个抽象类,如果其中没有其他合适的函数,可以把析构函数定义为纯虚的。...在析构的时候会首先调用子类的析构函数,析构掉对象中的子类部分,然后在调用基类的析构函数析构基类部分,如果在基类的析构函数里面调用虚函数,会导致其调用已经析构了的子类对象里面的函数,这是非常危险的。...虚拟继承与普通继承不同的是,虚拟继承可以防止出现diamond继承时,一个派生类中同时出现了两个基类的子对象。也就是说,为了保证这一点,在虚拟继承情况下,基类子对象的布局是不同于普通继承的。
【C++】C++中的继承,看这一篇就够了 一.继承的概念及定义 继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展...子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义。...派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。 派生类对象初始化先调用基类构造再调派生类构造。...派生类对象析构清理先调用派生类析构再调基类的析构。 因为后续一些场景析构函数需要构成重写,重写的条件之一是函数名相同。...那么编译器会对析构函数名进行特殊处理,处理成destrutor(),所以父类析构函数不加virtual的情况下,子类析构函数和父类析构函数构成隐藏关系 五.
那么我们很自然的想到在派生类析构函数中调用基类析构: 但是报错了??? 因为子类的析构也会隐藏父类的析构!!!...其实,派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。...所以我们不必在派生类的析构函数中进行调用基类的析构函数,不然就会重复释放同一块空间,导致报错! 因为析构必须要按先子后父的顺序,父亲没了何谈子呢?...派生类对象析构清理先调用派生类析构再调基类的析构。 因为后续一些场景析构函数需要构成重写,重写的条件之一是函数名相同(这个我们后面会讲解)。...那么编译器会对析构函数名进行特殊处理,处理成destrutor(),所以父类析构函数不加virtual的情况下,子类析构函数和父类析构函数构成隐藏关系 4 继承与友元 一句话:友元关系不能继承!!!
继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。...子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏, 也叫重定义。...派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能 保证派生类对象先清理派生类成员再清理基类成员的顺序。 派生类对象初始化先调用基类构造再调派生类构造。...派生类对象析构清理先调用派生类析构再调基类的析构。 因为后续一些场景析构函数需要构成重写,重写的条件之一是函数名相同(这个我们后面会讲 解)。...那么编译器会对析构函数名进行特殊处理,处理成destrutor(),所以父类析构函数不加 virtual的情况下,子类析构函数和父类析构函数构成隐藏关系。 构造是先父后子,析构是先子后父。
基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私 有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它。 2....三、继承中的作用域 1. 在继承体系中基类和派生类都有独立的作用域,所以可以有同名成员。 2. 子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏, 也叫重定义。...注意子类不能帮父类初始化,父类只能调用自己的构造函数,不能让子类去“帮忙” 注意构造函数调用顺序是先父后子,因为初始化列表初始化的顺序跟出现的顺序无关,跟声明的顺序有关 2、析构函数 子类的析构函数和父类的析构函数构成隐藏关系...为了保证先调用子类的析构函数,父亲的析构会在子类析构后自动调用。 构造:先父后子 析构:先子后父 为什么析构函数是先子后父呢?...假设析构走先父,后子是存在安全隐患的: 可能父类资源已经清理释放了,子类析构函数又去访问,存在野指针的风险。 总结: 派生这些默认成员函数规则,其实跟以前类似。
析构函数允许类自动完成类似清理工作,不必调用其他成员函数。 析构函数也是特殊的类成员函数。简单来说,析构函数与构造函数的作用正好相反,它用来完成对象被删除前的一些清理工作,也就是专门的扫尾工作。...声明方法与一般(无继承关系时)类的析构函数相同,不需要显式地调用基类的析构函数,系统会自动隐式调用。需要注意的是,析构函数的调用次序与构造函数相反。 初始化列表和构造函数初始化的区别?...首先想到的是在C++ 中,子类的构造函数会自动调用父类的构造函数。同样,子类的析构函数也会自动调用父类的析构函数。要想一个类不能被继承,我们只要把它的构造函数和析构函 数都定义为私有函数。...那么当一个类试图从它那继承的时候,必然会由于试图调用构造函数、析构函数而导致编译错误。 可是这个类的构造函数和析构函数都是私有函数了,我们怎样才能得到该类的实例呢?...基类析构函数未声明virtual,基类指针指向派生类时,delete指针不调用派生类析构函数。有 virtual,则先调用派生类析构再调用基类析构。 C++如何实现多态? C++中通过虚函数实现多态。
子类析构函数和父类析构函数构成隐藏关系。...因此,析构这里也需要与前三部分的不同:析构不需要像前三个一样显示调用对应的基类的析构函数,而是会自动生成基类的析构函数。因此,不必在派生类的析构函数中调用基类的析构,而是会自动生成。...发现顺序: 构造: 基类先构造,派生类后构造。 析构: 派生类先析构,基类后析构。 4.5 总结 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。...派生类的operator=必须要调用基类的operator=完成基类的复制。 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。...那么编译器会对析构函数名进行特殊处理,处理成destrutor(),所以父类析构函数不加virtual的情况下,子类析构函数和父类析构函数构成隐藏关系。
在继承体系中基类和派生类都有独立的作用域。 2. 子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义。...派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。 5. 派生类对象初始化先调用基类构造再调派生类构造。 6....派生类对象析构清理先调用派生类析构再调基类的析构。 7. 因为后续一些场景析构函数需要构成重写,重写的条件之一是函数名相同(这个我们后面会讲解)。...那么编译器会对析构函数名进行特殊处理,处理成destrutor(),所以父类析构函数不加virtual的情况下,子类析构函数和父类析构函数构成隐 注意: 1、构造的时候一定要先父后子,因为如果先子的话有可能会出现子类初始化出现父类成员...2、析构的时候一定要先子后父,因为子类析构时可能会用到父类。 继承与友元 友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员。
领取专属 10元无门槛券
手把手带您无忧上云