c++学习笔记之继承和多态

简介: 1、public 继承class A : public B(1)友元函数不能被继承(2)protected成员可以被派生类和友元访问

1、public 继承


class A : public B


(1)友元函数不能被继承


(2)protected成员可以被派生类和友元访问


2、派生类



(1)派生类构造函数如果未显式调用基类构造函数,则会隐式调用基类默认构造函数,没有则报错。


(2)派生类头文件中#include包含基类头文件


(3)派生类调用基类函数(已在派生类中重新定义过)

    基类名::基类函数          如 B::b(...)

    重新定义函数时一般会调用其基类函数,如果不加“基类名::”则会调用自己,形成无限递归。


(4)派生类有一个与基类中同名但签名不同的成员函数,那么会隐藏基类的那个成员函数。如:

    基类A有一个成员函数  void go(int i)

    派生类B有                  void go(int i, int j)

    b.go(1)会编译报错参数太少。(如果派生类没有go函数,则会直接调用基类的)


(5)多层派生关系:构造函数会从基类->派生类的顺序调用,析构函数则相反。


(6)派生类不会继承基类的构造函数、析构函数和重载的运算符。


3、public/private/protected 继承


继承public基类:基类的public成员成为派生类public成员,protected成员成为派生类的protected成员,派生类不能直接访问基类private成员。


继承protected基类:基类的public、protected成员成为派生类的protected成员,派生类不能直接访问基类private成员。


继承private基类:基类的public、protected成员成为派生类的private成员,派生类不能直接访问基类private成员。


4、基类、派生类指针


(1)基类指针指向派生类对象,可以调用基类成员,调用派生类成员则报错,但可以将基类指针显式强转成派生类指针就可以调用了。所以句柄类型决定哪个类函数被调用。


(2)派生类指针指向基类对象,编译错误。


5、virtual


virtual void a(...)

当通过指针调用virtual函数,则不再根据句柄来决定,而是根据指针所指的对象的类型选择合适的函数调用。


(1)一个函数声明为virtual,那么从整个继承层次的那一点向下所有类中都保持virtual,即使派生类重载此函数时并没有显式的声明virtual。

所以重载最好也显式声明virtual。


(2)当virtual函数通过按名引用被调用,如a.b(),调用哪个函数在编译时已经决定,即静态绑定,并不是多态性行为。

因此动态绑定只能通过指针句柄来完成。


6、抽象类


通过声明类的一个或多个virtual函数为纯virtual函数,可以使一个类成为抽象类。

纯virtual函数  virtual void a(...) const = 0;

“=0”称为纯指示符。

派生类必须重载纯virtual函数,否则实例化时编译报错。


7、运行时类型信息RTTI(dynamic_cast\typeid\type_info)


dynamic_cast(...)  向下强制类型转换

typeid(...)返回一个type_info对象的引用,其成员函数name()返回typeid实参的类型名称字符串(如“Class A”)。注意这个字符串与编译器有关,不同编译器可能不同。


8、virtual析构函数


删除一个派生类对象却使用基类指针,这样就无法调用派生类析构函数,会报行为未定义错误。

解决方法是声明基类析构函数为virtual,即使派生类析构函数与基类的不同名,也可以使这些析构函数为virtual函数,这时删除就能正常销毁。

(1)如果一个类会有virtual函数,就要提供一个virtual析构函数


(2)构造函数不能声明为virtual


目录
相关文章
|
3月前
|
存储 人工智能 编译器
c++--多态
上一篇文章已经介绍了c++的继承,那么这篇文章将会介绍多态。看完多态的概念,你一定会感觉脑子雾蒙蒙的,那么我们先以举一个例子,来给这朦胧大致勾勒出一个画面,在此之前,先介绍一个名词虚函数,(要注意与虚拟继承区分)重定义: 重定义(隐藏)只要求函数名相同(但要符合重载的要求,其实两者实际上就是重载);重定义下:在这种情况下,如果通过父类指针或引用调用函数,会调用父类的函数而不是子类。重定义(或称为隐藏)发生的原因是因为函数名相同但参数列表不同,导致编译器无法确定调用哪一个版本的函数。
63 0
|
3月前
|
存储 安全 Java
c++--继承
c++作为面向对象的语言三大特点其中之一就是继承,那么继承到底有何奥妙呢?继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用,继承就是类方法的复用。
79 0
|
6月前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
311 6
|
7月前
|
编译器 C++
c++中的多态
c++中的多态
|
6月前
|
存储 编译器 C++
【c++】多态(多态的概念及实现、虚函数重写、纯虚函数和抽象类、虚函数表、多态的实现过程)
本文介绍了面向对象编程中的多态特性,涵盖其概念、实现条件及原理。多态指“一个接口,多种实现”,通过基类指针或引用来调用不同派生类的重写虚函数,实现运行时多态。文中详细解释了虚函数、虚函数表(vtable)、纯虚函数与抽象类的概念,并通过代码示例展示了多态的具体应用。此外,还讨论了动态绑定和静态绑定的区别,帮助读者深入理解多态机制。最后总结了多态在编程中的重要性和应用场景。 文章结构清晰,从基础到深入,适合初学者和有一定基础的开发者学习。如果你觉得内容有帮助,请点赞支持。 ❤❤❤
725 0
|
8月前
|
C++ 开发者
C++学习之继承
通过继承,C++可以实现代码重用、扩展类的功能并支持多态性。理解继承的类型、重写与重载、多重继承及其相关问题,对于掌握C++面向对象编程至关重要。希望本文能为您的C++学习和开发提供实用的指导。
127 16
|
8月前
|
编译器 数据安全/隐私保护 C++
【C++面向对象——继承与派生】派生类的应用(头歌实践教学平台习题)【合集】
本实验旨在学习类的继承关系、不同继承方式下的访问控制及利用虚基类解决二义性问题。主要内容包括: 1. **类的继承关系基础概念**:介绍继承的定义及声明派生类的语法。 2. **不同继承方式下对基类成员的访问控制**:详细说明`public`、`private`和`protected`继承方式对基类成员的访问权限影响。 3. **利用虚基类解决二义性问题**:解释多继承中可能出现的二义性及其解决方案——虚基类。 实验任务要求从`people`类派生出`student`、`teacher`、`graduate`和`TA`类,添加特定属性并测试这些类的功能。最终通过创建教师和助教实例,验证代码
171 5
|
10月前
|
编译器 C++ 开发者
【C++】继承
C++中的继承是面向对象编程的核心特性之一,允许派生类继承基类的属性和方法,实现代码复用和类的层次结构。继承有三种类型:公有、私有和受保护继承,每种类型决定了派生类如何访问基类成员。此外,继承还涉及构造函数、析构函数、拷贝构造函数和赋值运算符的调用规则,以及解决多继承带来的二义性和数据冗余问题的虚拟继承。在设计类时,应谨慎选择继承和组合,以降低耦合度并提高代码的可维护性。
127 1
【C++】继承
|
10月前
|
存储 编译器 数据安全/隐私保护
【C++】多态
多态是面向对象编程中的重要特性,允许通过基类引用调用派生类的具体方法,实现代码的灵活性和扩展性。其核心机制包括虚函数、动态绑定及继承。通过声明虚函数并让派生类重写这些函数,可以在运行时决定具体调用哪个版本的方法。此外,多态还涉及虚函数表(vtable)的使用,其中存储了虚函数的指针,确保调用正确的实现。为了防止资源泄露,基类的析构函数应声明为虚函数。多态的底层实现涉及对象内部的虚函数表指针,指向特定于类的虚函数表,支持动态方法解析。
106 1
|
11月前
|
安全 编译器 程序员
C++的忠实粉丝-继承的热情(1)
C++的忠实粉丝-继承的热情(1)
86 0