​C++面向对象思想及封装、继承、多态、模板编程 目录一、OOP 四大核心特性多态1. 静态多态编译多态2. 动态多态运行多态5. 纯虚函数 抽象类6. 重写 (override)、重载 (overload)、重定义 (hide) 三者区别二、模板泛型编程 模板编译原理1. 模板是什么2. 函数模板3. 类模板4. 模板特化一、OOP 四大核心特性封装、继承、多态、抽象抽象提取事务的共性行为共性和属性共性封装将对象的属性和行为捆绑在一起并控制外部访问权捆绑 访问控制 对外统一接口继承公有继承私有继承保护继承构造顺序先构造父类再构造子类析构顺序先析构子类再析构父类​重要坑父类析构必须加 virtual多态前提如果父类析构不加 virtual父类指针指向子类对象delete 时只会调用父类析构子类资源泄漏。同名隐藏重定义子类定义和父类同名函数无 virtual会隐藏父类所有同名重载函数叫静态重定义不构成多态。继承分类单继承一个子类只继承一个父类多继承一个子类继承多个父类C 支持Java 不支持问题菱形继承钻石继承带来二义性、数据冗余解决方案虚继承 virtual public共享一份父类成员。多层继承A→B→C多态同一个接口不同对象表现不同行为。一句话一个接口多种实现。分类静态多态动态多态1. 静态多态编译多态编译器在编译阶段就能确定调用哪个函数。两种实现函数重载同一作用域函数名相同参数列表不同个数 / 类型 / 顺序返回值不能区分重载。运算符重载特点早绑定编译期确定地址效率高。2. 动态多态运行多态运行时才能确定调用哪个函数必须同时满足 3 个条件公有继承public 继承父类中有虚函数 virtual子类重写该虚函数重写 override使用父类指针 / 引用指向子类对象调用函数4. 动态多态底层原理虚函数表 vtable、虚函数指针 vptr含有虚函数Base的类会生成一张虚函数表vtable这个虚表里有所有的虚函数的地址这个类的对象头部会生成一个虚指针指向这个虚表在son子类继承Base的时候son也会生成一张属于自己的虚函数表vtablevtable中有已经被重写的父类虚函数未被重写的父类虚函数和自己新增的虚函数。也会在子类生成的对象头部生成一个虚指针指向虚函数表。程序运行时会根据指针拿到子类对象的内存起始地址再由内存起始地址找到vptr因为vptr在对象的头部在找到自己的虚表再读出虚表中函数的真实地址最后执行该函数。5. 纯虚函数 抽象类纯虚函数virtual void func() 0;包含纯虚函数的类叫抽象类不能实例化只能被继承。作用定义接口规范强制子类必须重写所有纯虚函数否则子类仍是抽象类。6. 重写 (override)、重载 (overload)、重定义 (hide) 三者区别特性重载 overload重写 override重定义 hide作用域同一个类父子类父子类virtual不需要必须父类 virtual无 virtual参数参数必须不同参数完全一致名字相同即可绑定编译期静态运行期动态编译静态二、模板泛型编程 模板编译原理1. 模板是什么泛型编程编写与类型无关的代码一套代码适配多种数据类型消除重复逻辑。两种模板函数模板、类模板2. 函数模板templatetypename T // templateclass T 等价 T add(T a, T b){ return a b; } // 使用 add(1,2); // Tint add(1.5,2.2); // Tdoubletypename/class 无区别推荐 typename 区分类类型。模板参数可以多个templateT1,T23. 类模板templateclass T class Stack{ private: T arr[100]; public: void push(T val){} }; // 实例化必须指定类型 Stackint st1; Stackstring st2;4. 模板特化1全特化为某一个特定类型单独实现模板template class Stackchar{ // char类型专属逻辑 };2偏特化部分模板参数固定多参数模板适用5. 模板编译原理重要1. 模板两阶段编译C 标准阶段 1模板定义检查只检查语法不实例化编译器读取模板代码只做基础语法校验少分号、关键字错误不校验类型相关逻辑。哪怕 T 类型没有 运算符只要语法没错这一阶段不会报错。阶段 2模板实例化时检查使用模板时当代码调用addint、Stackstring编译器触发隐式实例化根据传入的实参 类型生成一份对应类型的真实函数 / 类代码。模板本身不生成代码只有实例化才会生成二进制代码。不同类型实例化生成多份独立代码addint、adddouble是两个完全不同函数。2. 实例化分类隐式实例化使用模板自动生成代码日常开发显式实例化手动强制生成指定类型代码template int addint(int,int);3. 模板代码分离问题错误写法模板声明放.h实现放.cpp问题编译.cpp 时无实例化不会生成对应类型代码主函数链接时找不到函数定义报链接错误。解决方案二选一模板声明与实现全部写在头文件.h 中工程最常用.cpp 末尾添加显式实例化指定所有需要用到的类型。————————————————————————-———————————————本文讲解到处结束有问题欢迎给我留言​