C++03:论类的虚函数和纯虚函数
时间:2019-07-05
本文章向大家介绍C++03:论类的虚函数和纯虚函数,主要包括C++03:论类的虚函数和纯虚函数使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一、虚函数
1.虚函数的作用
主要是实现了多态的机制,简而言之就是用父类(基类)的指针指向子类(派生类)的对象,然后通过父类(基类)的指针调用不同子类(派生类)的对象的不同函数,这就是一种泛型.
虚函数通过继承,来实现多态(虚函数动态绑定),最后达到封装的效果
一个公有派生类对象可以赋值给基类的对象,但是基类的对象不能赋值给派生类的对象
虚函数一般用于基类成员函数来绑定派生类成员函数一起调用
2.虚函数的使用
//1.在基类用virtual声明成员函数为虚函数, class Base{ virtual void A(); }; //在类外定义虚函数无需加virtual void Base::A(){ } //2.在派生类重新定义虚函数,要求函数名/函数类型/函数参数的类型和个数保持一致 class Derive : pubic Base{ //虚函数在派生类重新声明时,无需加virtual void A(); }; //3.定义一个指向基类对象的指针变量,并使用基类对象的指针变量指向不同的派生类对象的函数 void main(){ Base* p=new Derive(); p->A(); }
class Base { public: Base() {echo();} virtual void echo() {printf(“Base”);} }; class Derived:public Base { public: Derived() {echo();} virtual void echo() {printf(“Derived”);} }; int main() { Base* base = new Derived(); base->echo(); //输出Base Derived Derived return 0; }
二.虚析构函数
虚析构函数的作用是delete动态对象时释放资源
//test.h class A{ public: char* strA; A(char* a){ strA=new char[12]; strncpy(strA,a,strlen(a)); } virtual ~A(){ //不加virtual会报错 delete strA; } }; class B:public A{ public: char* strB; B(char* a):A(a){ strB=new char[12]; strncpy(strB,a,strlen(a)); } ~B(){ delete strB; } }; //test.cpp int main(){ char input[]="Hello"; A* a=new B(input); delete[] a; system("pause"); return 0; }
三、纯虚函数
1.虚函数和纯虚函数的关联
(1)在虚函数的声明语句末尾加个=0,就变成了纯虚函数
(2)虚函数和纯虚函数在基类都可以提供其实现的代码,子类可以调用基类的这些实现
(3)子类可以选择是否实现虚函数,但是子类必须实现纯虚函数
四.动态绑定
#include <iostream> using namespace std; class A { public: virtual void func(int val = 1) { std::cout " << val << std::endl; } virtual void test() { func(); } }; class B : public A { public: void func(int val = 0) { std::cout " << val << std::endl; } }; int main(int argc, char* argv[]) { A*p1 = new A; A*p2 = new B; //B*p3 = new A; //error B*p3 = reinterpret_cast<B*> (new A); B*p4 = new B; //测试test() p1->test(); //A->1 p2->test(); //B->1 p3->test(); //A->1 p4->test(); //B->1 //测试func() p1->func(); //A->1 p2->func(); //B->1 p3->func(); //A->0 p4->func(); //B->0 return 0; }
#include <iostream> using namespace std; class A { public: void func(int val = 1) { std::cout " << val << std::endl; } //这个test()的virtual可有可无 virtual void test() { func(); } }; class B : public A { public: void func(int val = 0) { std::cout " << val << std::endl; } }; int main(int argc, char* argv[]) { A*p1 = new A; A*p2 = new B; //B*p3 = new A; //error B*p3 = reinterpret_cast<B*> (new A); B*p4 = new B; //test() p1->test(); //A->1 p2->test(); //A->1 p3->test(); //A->1 p4->test(); //A->1 //func() p1->func(); //A->1 p2->func(); //A->1 p3->func(); //B->0 p4->func(); //B->0 return 0; }
原文地址:https://www.cnblogs.com/k5bg/p/11136618.html
- 【Go 语言社区】Go 语言范围(Range)
- 【Go 语言社区】JS 相关---Window Location
- 【Go 语言社区】Go 语言Map(集合)
- 【Go 语言社区】JavaScript Date(日期)对象
- UWP基础教程 - XAML类型转换器
- Oracle 12c Data Guard搭建(一) (r10笔记第57天)
- 【Go 语言社区】Go语言 Cookie的使用
- 【Go 语言社区】HTML5 Geolocation(地理定位)-转
- Oracle 12c PDB迁移(一)(r10笔记第56天)
- 【Go 语言社区】Go worker线程池
- Oracle 12C打补丁的简单尝试(r10笔记第55天)
- 【Go 语言社区】奇妙的go语言(网页下载)-转
- 【Go 语言社区】golang的bufio用于内容解析
- [Go语言]从Docker源码学习Go——指针和Structs - lemon_bar
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- linux查找大文件指定内容的实现方法
- linux服务器上安装jdk的两种方法(yum+下载包)
- ubuntu中编写shell脚本开机自动启动(推荐)
- linux下使用 CentOS7安装jdk1.7
- 安装CentOS 6.x报错"Disk sda contains BIOS RAID metadata"解决方法
- 重启宝塔面板后提示-ModuleNotFoundError: No module named 'geventwebsocket'
- Linux动态启用/禁用超线程技术的方法详解
- 解决Ubuntu下使用linuxdeployqt打包Qt程序问题
- 使用python获取基金历史数据
- 如何在CentOS8上安装和配置Postfix邮件服务器的方法示例
- Linux下设置Vim编辑器里Tab的长度行号
- Centos定制rpm包、搭建yum仓库的教程
- linux手动、自动更改网卡MAC地址的方法
- Centos7的Firewalld防火墙基础命令详解
- Linux下安装或升级Python 2.7的操作方法