首页
学习
活动
专区
圈层
工具
发布

C++系列笔记(五)

首先,根本没有调用Fish::Swim() ,因为存在覆盖版本 Tuna::Swim()和 Carp::Swim() ,它们优先于被声明为虚函数的Fish::Swim()。...,还是以局部变量的方式在栈中实例化的,构造函数和析构函数的调用顺序都相同。...抽象基类和纯虚函数 不能实例化的基类被称为抽象基类,这样的基类只有一个用途,那就是从它派生出其他类。在 C++中,要创建抽象基类,可声明纯虚函数。...注意:C++关键字virtual的含义随上下文而异(我想这样做的目的很可能是为了省事),对其含义总结如下: 在函数声明中,virtual意味着当基类指针指向派生对象时,通过它可调用派生类的相应函数。...可将复制构造函数声明为虚函数吗 根本不可能实现虚复制构造函数,因为在基类方法声明中使用关键字virtual时,表示它将被派生类的实现覆盖,这种多态行为是在运行阶段实现的。

1K30

【C++】多态 ⑬ ( 多继承中应用 “ 抽象类 “ | 接口和抽象类 | C++ 语言中接口实现 | 只定义 纯虚函数 的 抽象类作接口 | )

一、多继承中应用 " 抽象类 " 1、接口和抽象类 接口 Interface 和 抽象类 AbstractClass 都是 面向对象编程 的重要概念 , 借助它们可以定义一个模板 , 令其他类 实现接口...语言中接口实现 C++ 语言中 , 没有接口概念 , 这里使用 " 纯虚函数 " 实现接口 ; 接口类特点 : 接口类中 只有 函数原型 , 没有成员变量 , 函数原型 指的是 函数只有 返回值 函数名...和 参数列表 , 没有函数体 ; C++ 中的 接口类 有如下要求 : 类中只能定义纯虚函数 , 该类是一个抽象类 ; 类中不能定义除纯虚函数之外的其它成员 , 如 普通函数 , 成员变量 ; 下面的类就是...virtual void pureVirtualFunction() = 0; }; 二、代码示例 - 多继承中应用 " 抽象类 " 在 C++ 中 , 使用只定义了 纯虚函数 的 抽象类 ,...作为接口 ; 借助 C++ 多继承的特性 , 继承多个 " 只定义了 纯虚函数 的 抽象类 " , 也就是接口 ; 代码示例 : #include "iostream" using namespace

66220
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    十一、多态

    在C++中,多态主要通过虚函数来实现,并涉及以下三个关键要素: 继承关系 说明:多态必须发生在具有继承关系的类之间。即,一个类(子类或派生类)必须从另一个类(父类或基类)继承而来。...总结 C++多态的三要素可以概括为: 继承关系:子类继承自基类,为多态提供了基础。 虚函数:基类中声明为virtual的函数,允许子类进行重写。...函数的重载、重写、重定义 函数重载 必须在同一个类中进行(作用域相同) 子类无法重载父类的函数,父类同名函数将被名称覆盖 重载是在编译期间根据参数类型和个数决定函数调用 函数重定义 发生于父类和子类之间...纯虚函数和抽象类 在面向对象编程(OOP)中,纯虚函数和抽象类是两个重要的概念,它们主要用于实现多态性和定义接口。这两个概念在C++等语言中特别常见,但也存在于其他支持面向对象编程的语言中。...__vfptr(但在标准C++中并没有直接暴露这个名称,它是编译器内部实现的细节)。

    78510

    封装、继承、多态、重载:C++中的强大特性与代码设计

    在main函数中,我们分别创建了Shape对象和Rectangle对象,并调用了它们的draw函数。 继承是一种强大的代码复用工具,它可以使得类之间的关系更加清晰和有组织。...overload 成员函数被重载的特征: 相同的范围(在同一类中) 函数名字相同 参数不同 virtual关键字可有可无 overwrite 覆盖是指派生类函数覆盖基类函数 特征是: 不同的范围...派生类中必须实现基类中的纯虚函数,否则被看做一个抽象类 对于一个没有任何接口的类,如果想要将它定义成抽象类,只能将虚构函数声明为纯虚的 通常情况下在基类中纯虚函数不需要实现,例外是纯析构函数要给出实现...重载 在C++中,函数重载(Function Overloading)是指在同一个作用域内,可以定义多个具有相同名称但参数列表不同的函数。...通过函数重载,可以根据参数的类型、顺序和个数来区分不同的函数,并且可以为相同的操作提供不同的实现。 函数重载的特点如下: 函数名称相同:重载的函数必须具有相同的名称。

    97510

    【C++】从静态到动态:多态的诗意旅程

    前言 这是我自己学习C++的第八篇博客总结。后期我会继续把C++学习笔记开源至博客上。...虚函数的重写、覆盖:派生类中有一个跟基类 完全相同的虚函数 (即派生类虚函数与基类虚函数的 返回值类型、函数名字、参数列表完全相同 ),称派生类的虚函数重写了基类的虚函数。 析构函数重写 1....包含纯虚函数的类 叫做 抽象类 ,抽象类 不能实例化出对象 ,如果派生类继承后不重写纯虚函数,那么派生类也是抽象类。 4....这个虚函数表指针和单独创建的基类对象的虚函数表指针是独立的,尽管它们可能指向相同的虚函数表(或经过派生类调整后的虚函数表)。 5. 虚函数表的内容会根据派生类是否重写了基类的虚函数而动态调整。...派生类中重写的基类的虚函数,派生类的虚函数表中对应的虚函数就会被覆盖成派生类重写的虚函数地址。 致谢 感谢您花时间阅读这篇文章!

    31910

    【C++】“多态”特性

    在派生类中重写基类虚函数时,派生类的虚函数前可以不加virtual修饰,也可以构成重写,因为继承后基类的虚函数在派生类中仍保持虚函数属性。...四、重载/重写/隐藏的对比 这三个概念比较相近,要注意区别: 函数重载: 两个函数在同一作用域 函数名相同,参数的类型或个数不同,返回值可同可不同 虚函数重写: 两个函数分别在一个继承体系的基类和派生类中...函数名、参数、返回值相同,协变除外 两个函数必须都是虚函数 隐藏: 两个函数分别在一个继承体系的基类和派生类中 函数名相同 两个函数只要不构成重写,就是隐藏关系 基类和派生类的成员变量相同也构成隐藏关系...包含纯虚函数的类称为抽象类,抽象类不能实例化出对象,如果一个抽象类的派生类继承后不重写纯虚函数,则派生类也是抽象类。可以认为,纯虚函数一定程度上强制派生类重写虚函数,因为不重写不实例化出对象。...派生类重写了基类的虚函数后,派生类的虚表中对应的原基类虚函数就会被覆盖成派生类重写的虚函数地址。这也是为什么重写也可以称为覆盖。

    11510

    【C++篇】灵动之韵:C++多态之舞,赋予代码生命的艺术

    本篇重点在于运行时多态 1.3 实现多态的条件 要实现 C++ 中的运行时多态,需要满足以下条件: 继承:基类和派生类之间存在继承关系。...2.4 纯虚函数与抽象类 2.4.1 纯虚函数的定义 纯虚函数是一种特殊的虚函数,它在基类中没有实现,仅仅是一个接口的声明。...2.5 覆盖、隐藏与重载(易混淆点解析) 在多态中,理解覆盖、隐藏和重载的区别非常重要: 覆盖(Override):派生类重新定义基类中声明为 virtual 的函数,函数签名相同。...虽然函数名不相同,看起来违背了重写的规则,其实不然,这里可以理解为编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理成destructor。...然而,多态的神奇远不止于此。接下来,我们将一起深入探讨多态背后的实现原理,揭开虚函数表(VTable)如何实现动态绑定的奥秘,以及如何在多重继承的复杂关系中应对多态的挑战。

    54410

    【c++】多态(一)

    二、多态的定义和实现 多态是一个继承关系下的类对象(基类对象与派生类对象),用指向它们的基类指针去调用同一个函数,由于指向的对象不同,因而产生了不同的行为。...比如,有基类Person与派生类Student对象p和,调用同一个买票函数,用Person类指针ptr分别指向它们,结果是对象p买全价票,对象s买学生票,它们产生了不同的结果。...,满足三同:函数名相同,参数列表与返回值完全相同,那么称派生类的虚函数重写了基类的虚函数。...所以基类中的析构函数建议设计为虚函数。...包含纯虚函数的类就做抽象类,抽象类不能实例化出对象,如果派生类继承后不重写纯虚函数,那么派生类也是抽象类。 纯虚函数某种程度上强制了派生类重写虚函数,因为不重写实例化不出对象。

    5110

    c#中的多态学习总结

    c#的多台方法,大体上和c++的类似,但是有点区别的,我这里刚刚初学,因此把重点记录下。 多态是同一个行为具有多个不同表现形式或形态的能力。 多态性意味着有多重形式。...分别为: 函数重载和运算符重载,运算符重载后续讨论,这里讨论函数重载。英文是overload,和c++的基本类似。 重载有一点是特别注意:不能通过返回值来重载,只能通过函数的参数进行重载。...记得在侯捷的视频中,大师提到过,函数名是一样的,但是编译器其实已经做了标记,在底层函数名称是不一样。 函数重载和c++类似,这里不细谈了。总之一点就通过函数参数来重载的。...c++也有抽象类,只要定义了纯虚函数的都成为抽象类,纯虚函数:virtual void area() = 0; //定义纯虚函数,用来某形状计算面积而且不能实例化,只能被继承后,由派生类来实例化...重载在同一个作用域(一般指一个类)的两个或多个方法函数名相同,参数列表不同的方法叫做重载,它们有三个特点(俗称两必须一可以): a.方法名必须相同 b.参数列表必须不相同 c.返回值类型可以不相同

    1.1K20

    今天你学C++了吗?——C++中的多态

    析构函数的名称与类名相同,但前面有一个波浪号(~) 基类中的虚析构函数 当基类指针指向派生类对象时(多态性),如果基类的析构函数不是虚函数,那么在删除这个指针时,只会调用基类的析构函数,而不会调用派生类的析构函数...重写/覆盖(Overriding) 定义:在类的继承关系中,子类提供一个与基类中的虚函数具有相同签名(函数名、参数列表和返回类型相同)的函数实现。 范围:重写发生在基类和子类之间。...重写/覆盖是在继承关系中,子类提供基类虚函数的特定实现,实现多态性。 隐藏是在继承关系中,由于函数签名不匹配或作用域不同,子类函数屏蔽了基类中的同名函数,通常不是有意为之的。...,它在类中被声明为 = 0 包含纯虚函数的类被称为抽象类,抽象类不能创建对象,它们的主要作用是提供一个接口或规范,要求继承它们的子类必须实现这些纯虚函数。...派生类的虚函数表包含三个部分:一是从基类继承而来的虚函数地址(如果它们没有被派生类重写);二是派生类重写的虚函数地址(这些地址会覆盖基类虚函数表中的相应地址);三是派生类自己定义的新的虚函数地址。

    64000

    【探寻C++之旅】第八章:多态

    这里我们的virtuai关键字与上一章继承中虚继承的virtual关键字相同,不过它们之间并没有什么联系,只是一个关键字两个不同的用处。...,就是派生类中有一个跟基类中完全相同的虚函数,这里的完全相同指的是返回值类型相同、函数名字相同、参数列表相同。...最后的最后关于虚函数的重写还有一个小点,对于派生类中重写基类的虚函数,我们可以理解为是将基类的虚函数中除了函数体中的内容剩下的都覆盖到派生类的虚函数上,也就是说,当我们在派生类中重写一个基类的虚函数时,...),返回值无要求 重写: 两个函数都必须是虚函数 两个函数分别在继承体系的基类和派生类中,不能在同一作用域 两个函数都必须满足函数名、参数、返回值都相同 隐藏: 两个函数分别在继承体系的基类和派生类中...如果派⽣类中重写的基类的虚函数,那么派⽣类的虚函数表中对应的虚函数的地址就会被覆盖成派⽣类重写的虚函数地址。

    27010

    C++ OOP面向对象

    Q: 面向对象特点 A: 封装,继承,多态 Q: 抽象类 A: 抽象类是特殊的类,只是不能被实例化(将定义了纯虚函数的类称为抽象类);除此以外,具有类的其他特性;抽象方法只能声明于抽象类中,且不包含任何实现...另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖,如果不覆盖,则其派生类必须覆盖它们。虽然不能定义抽象类的实例,但是可以定义它的指针,这正是用抽象类实现接口的重点所在。...Q: 虚函数 A: C++实现运行中的多态性是通过虚函数实现的,而虚函数必须存在于继承环境下。 虚函数是重载的一种表现形式,是一种动态的重载方式。...因为虚函数的作用是允许在派生类中对基类的虚函数重新定义。所以虚函数只能用于类的继承层次结构中。...,由该基类所派生的所有派生类的析构函数都自动成为虚函数,即使派生类的析构函数与基类的析构函数名字不相同。

    1.1K10

    C++重要知识点小结---2

    这种类成为抽象类。 一个抽象类至少具有一个纯虚函数。所谓纯虚函数是指被标明为不具体实现的虚成员函数。...如: virtual void WithDrawal(float amount) = 0; //纯虚函数 在WithDrawal()的声明之后的“=0”表明程序员将不定义该函数。...如果在基类中没有保留位置,则就没有重载。 纯虚函数是一个没有定义函数语句的基类虚函数,纯虚函数的值是0.派生类必须为每一个基类纯虚函数提供一个相应的函数定义。...构造函数按下列顺序被调用: 任何虚拟基类的构造函数按照它们被继承的顺序构造; 任何非虚拟基类的构造函数按照它们被继承的顺序构造; 任何成员对象的构造函数按照它们声明的顺序调用; 类自己的构造函数。...纯虚函数 C++的纯虚函数用于表示一个类不能被创建实例, 必需是子类覆盖该方法的定义后,方可新建类实例,格式是在虚函数后面添加 = 0。

    94270

    《C++进阶之继承多态》【多态:概念 + 实现 + 拓展 + 原理】

    尽管基类析构函数(如:~Base())和派生类析构函数(如:~Derived())名字不同,看似不符合重写 “函数名相同” 的规则。...核心特点: 作用范围:发生在基类与派生类的继承关系中 名称覆盖:只要名称相同即会隐藏,与参数列表无关(即使派生类函数参数不同,基类同名函数也会被隐藏) 访问限制:若需访问基类被隐藏的成员,需用基类名...重写(Override):派生类中重新实现基类的虚函数,函数签名(名称、参数列表、返回值类型)必须与基类完全一致(C++11 后可用override关键字显式声明) 核心特点: 作用范围:仅发生在基类与派生类的继承关系中...绑定时机 编译期静态绑定 编译期名称覆盖 运行期动态绑定(多态) 参数要求 参数类型 / 数量 / 顺序不同 名称相同即可(参数无关) 必须与基类函数签名完全一致 典型场景 实现同功能不同参数的函数...在 C++ 中,纯虚函数通过在虚函数声明末尾添加 = 0 来标识 纯虚函数在基类中仅需声明而无需定义具体实现(语法上虽允许定义,但因必须由派生类重写,其基类实现通常并无实际意义) 语法示例: class

    19610

    【C++】多态到底难在哪?虚函数表 + 动态绑定,一篇吃透底层逻辑!

    而不同的派生类,比如表示“学生电费”的子类,虽然保留了相同的孔洞形状,但它们重写了插座后面实际连接的“电源系统”(覆盖实现)。...2.2 重写 / 覆盖 的例外(协变) 协变是对派生类重写基类的虚函数中必要条件之一 返回值类型相同的唯一松绑;它允许派生类的虚函数返回一个更具体(更窄)的类型。...2.4 析构函数重写成虚函数的原理 C++ 析构函数(Destructor)的重写机制是一个特殊的规则,它看似违反了虚函数重写中“函数名称必须相同”的必要条件,但实际上,这是语言标准为了保证多态的完整性而设立的例外...0; } 分别继承各个基类的虚表内容到派生类的各个虚表当中。...在派生类第一个继承基类部分的虚表当中新增派生类当中新的虚函数地址,比如func3。 这里我们可以发现在多继承的虚函数重写后,它们在对应的两张虚表中的地址不同,这是为什么?

    22410

    C++重要知识点小结---2

    这种类成为抽象类。 一个抽象类至少具有一个纯虚函数。所谓纯虚函数是指被标明为不具体实现的虚成员函数。...如: virtual void WithDrawal(float amount) = 0; //纯虚函数 在WithDrawal()的声明之后的“=0”表明程序员将不定义该函数。...如果在基类中没有保留位置,则就没有重载。 纯虚函数是一个没有定义函数语句的基类虚函数,纯虚函数的值是0.派生类必须为每一个基类纯虚函数提供一个相应的函数定义。...构造函数按下列顺序被调用: 任何虚拟基类的构造函数按照它们被继承的顺序构造; 任何非虚拟基类的构造函数按照它们被继承的顺序构造; 任何成员对象的构造函数按照它们声明的顺序调用; 类自己的构造函数。...纯虚函数 C++的纯虚函数用于表示一个类不能被创建实例, 必需是子类覆盖该方法的定义后,方可新建类实例,格式是在虚函数后面添加 = 0。

    1K70

    C++基础(七).多态(1)

    《C++ 虚函数&纯虚函数&抽象类&接口&虚基类》 《C++抽象基类和纯虚函数》 ---- 概要 ---- 多态 在面向对象语言中,接口的多种不同实现方式即为多态 多态特性中,可以将子类类型的指针赋值给父类类型的指针...在派生类中定义的函数应与虚函数具有相同的形参个数和形参类型(覆盖),以实现统一的接口,不同定义过程。...一般来说,接口类中只有纯虚函数的 4)带纯虚函数的类叫抽象类,这种基类不能直接生成对象,而只有被继承,并且重写其虚函数后,才能使用 ---- 抽象类 带有纯虚函数的类称为抽象类 抽象类是一种特殊的类,它是为了抽象和设计的目的而建立的...抽象类是不能定义对象的,在实际中为了强调一个类是抽象类,可将该类的构造函数说明为保护的访问控制权限 抽象类的主要作用是将有关的组织在一个继承层次结构中,由它来为它们提供一个公共的根,相关的子类是从这个根派生出来的...一个继承于抽象类的子类,只有实现了父类所有的抽象方法才能够是非抽象类 ---- 接口 接口只是一个概念,它在C++中用抽象类来实现 接口是专门被继承的,接口存在的意义也是被继承,和C++里的抽象类里的纯虚函数是相同的

    68120

    C++之多态的深度剖析

    虚函数的重写/覆盖: 派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型、函数名字、参数列表(类型,数量)完全相同),称派生类的虚函数重写了基类的虚函数。...故在C++中,当一个基类的析构函数被声明为虚函数时,它确保了当通过基类指针或引用删除派生类对象时,会调用正确的析构函数,即派生类的析构函数,然后再调用基类的析构函数。...override 关键字用于明确指出一个成员函数旨在重写(覆盖)其基类中的一个虚函数。如果该函数没有正确地重写基类中的任何虚函数,编译器将报错。...如果是函数,参数列表不必相同。 如果派生类中的成员与基类中的成员具有相同的名称,但不同的参数列表,则基类成员被隐藏,而不是重载或重写。...包含纯虚函数的类叫做抽象类,抽象类不能实例化出对象,如果派生类继承后不重写纯虚函数,那么派生类也是抽象类。纯虚函数某种程度上强制了派生类重写虚函数,因为不重写实例化不出对象。

    15310

    c++中的多态

    下面引出这两个条件:即多态出现的不得有继承关系么: 1.即基类对象指针或引用调用虚函数,(这时看传的对象如果是派生类对象就调派生类虚函数,如果是基类对象就去调基类虚函数) 2.即需要在父类的虚函数前加上...=0,而包含这个纯虚函数的类就是抽象类,不能实例化处对象如: virtual void talk() = 0; 这里也许会说为什么没内容,因为它已经是纯虚函数了,后面要想使用必须通过子类给它的定义重写了...②当子类如果继承了多个父类,则分别在继承的子类中的父类处有个虚表,则继承几个父类,有几个虚表但是没完成重写的虚函数直接加到第一个继承的父类的虚表中。...2·3原理总结(仅个人理解): 父类指针或者引用调用虚函数(访问谁的虚函数由传递给它的对象决定)子类继承父类在子类对应继承放父类的位置生成虚表,这个虚表中放的是父类虚函数的地址,然后子类如果能进行虚函数重写就给它重写定义完成覆盖操作...,最后这个虚表中也就是父的声明+子的定义(存放它们对应函数地址),当使用不同对象调用不同虚表中的虚函数。

    38810

    深入解析【C++多态】:探索面向对象编程中的动态绑定与行为多样性和多态的核心概念与应用实践

    虚函数的重写/覆盖 虚函数的重写/覆盖:派⽣类中有⼀个跟基类完全相同的虚函数(即派⽣类虚函数与基类虚函数的返回值 类型、函数名字、参数完全相同),称派⽣类的虚函数重写了基类的虚函数。...下面我们可以看到,基类和派生类它们都有个虚函数表(_vfptr)都分别指向虚函数。...但是要注意的这⾥继承下来的基类部分虚函数表指针和基 类对象的虚函数表指针不是同⼀个,就像基类对象的成员和派⽣类对象中的基类对象成员也独⽴ 的。...派⽣类中重写的基类的虚函数,派⽣类的虚函数表中对应的虚函数就会被覆盖成派⽣类重写的虚函 数地址。 派⽣类的虚函数表中包含,基类的虚函数地址,派⽣类重写的虚函数地址,派⽣类⾃⼰的虚函数地址这三个部分。...派⽣类中重写的基类的虚函数,派⽣类的虚函数表中对应的虚函数就会被覆盖成派⽣类重写的虚函 数地址。 func1和func2被继承下来了,派生类⾃⼰就不会再⽣成虚函数表指针,所以它们是同一个地址。

    42300
    领券