在C++里面,虚拟功能是功能的一类重要!不同目的可以通过在不同的虚拟功能来达到同样的动作被定义。

举一个简单的例子:

#include <iostream>
#include <string>
using namespace std;
class Animal{
protected:
string name;
public:
Animal(const string &s):name(s){
}
virtual ~Animal(){
}
virtual void speak()const{
cout<<"I'm a Animal!"<<endl;
}
};
class Dog:public Animal{
public:
Dog(const string &s):Animal(s){
}
virtual ~Dog(){
}
virtual void speak()const override{
cout<<"This's a Dog!"<<endl;
}
};
int main(){
Animal a("AnimalOne");
Dog d1("DogOne");
<span style="white-space:pre">	</span>//用指针调用speak()
Animal *p1=&a;
Animal *p2=&d1;
p1->speak();
p2->speak();
<span style="white-space:pre"> </span>//用引用调用speak()
Animal &r1=a;
Animal &r2=d1;
r1.speak();
r2.speak(); return 0; }

结果:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXE4NDQzNTIxNTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

能够看出,通过指针和引用能够调用相应的虚函数.即便指针和引用都声明为Animal 类型,可是却能够调用相应的函数(Dog::speak()).

因此,假设须要在派生类中又一次定义基类的方法,应该将该方法设置为虚方法.

须要注意的是仅仅有指针和引用才干正确引发对应的虚函数.同一时候函数必须声明为虚的.假设不是的话,将仅仅会调用对应的类成员函数.

比如:

#include <iostream>
#include <string>
using namespace std;
class Animal{
protected:
string name;
public:
Animal(const string &s):name(s){
}
virtual ~Animal(){
}
void speak()const{
cout<<"I'm a Animal!"<<endl;
}
};
class Dog:public Animal{
public:
Dog(const string &s):Animal(s){
}
virtual ~Dog(){
}
void speak()const {
cout<<"This's a Dog!"<<endl;
}
};
int main(){
Animal a("AnimalOne");
Dog d1("DogOne"); Animal *p1=&a;
Animal *p2=&d1;
p1->speak();
p2->speak(); Animal &r1=a;
Animal &r2=d1;
r1.speak();
r2.speak(); return 0; }

执行结果:



假设成员函数不是虚的,就不能达到这种效果.这就是动态绑定.

再看一个样例:

#include <iostream>
#include <string>
using namespace std;
class Animal{
protected:
string name;
public:
Animal(const string &s):name(s){
}
virtual ~Animal(){
} //非虚函数
void eat()const{
cout<<"Animal eat!"<<endl;
} //不被重写的虚函数
virtual void run()const{
cout<<"Animal run!"<<endl;
} //会被重写的虚函数
virtual void speak()const{
cout<<"I'm a Animal!"<<endl;
}
};
class Dog:public Animal{
public:
Dog(const string &s):Animal(s){
}
virtual ~Dog(){
} //新定义的函数eat,将掩盖旧的版本号,非重写(重写是指重写virtual函数)
void eat()const{
cout<<"Dog eat!"<<endl;
} //重写speak()
virtual void speak()const override{
cout<<"This's a Dog!"<<endl;
}
};
int main(){
Animal a("AnimalOne");
Dog d1("DogOne"); Animal *p1=&a;
Animal *p2=&d1;
p1->speak();
p2->speak();
p1->eat();
p2->eat(); //call Animal::eat()
p1->run();
p2->run(); //call Animal::run() Animal &r1=a;
Animal &r2=d1;
r1.speak();
r2.speak();
r1.eat();
r2.eat();
r1.run();
r2.run(); return 0; }

结果:

版权声明:本文博客原创文章,博客,未经同意,不得转载。

C++学习笔记26,虚函数的更多相关文章

  1. 学习笔记---C++虚函数,纯虚函数

    1 .虚函数 假设people是man的父类,people类和man类都定义了实函数walk() people* p = new man(); p->walk(); 这里P执行的是people类 ...

  2. C++学习笔记--从虚函数说开去

    虚函数与纯虚函数: 虚函数:在某基类中声明为virtual并在一个或多个派生类中被重新定义的成员函数,virtual  函数返回类型  函数名(参数表){函数体;} ,实现多态性,通过指向派生类的基类 ...

  3. C++学习笔记27,虚函数作品

    C++它指定虚函数的行为,但实现的作者编译器. 通常,编译器处理虚函数的方法是给每个对象加入一个隐藏成员.隐藏成员中保存了一个指向函数地址数组的指针. 这个数组称为虚函数表(virtual funct ...

  4. IOS学习笔记07---C语言函数-printf函数

    IOS学习笔记07---C语言函数-printf函数 0 7.C语言5-printf函数 ------------------------- ----------------------------- ...

  5. Typescript 学习笔记三:函数

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  6. Python学习笔记之常用函数及说明

    Python学习笔记之常用函数及说明 俗话说"好记性不如烂笔头",老祖宗们几千年总结出来的东西还是有些道理的,所以,常用的东西也要记下来,不记不知道,一记吓一跳,乖乖,函数咋这么多 ...

  7. IOS学习笔记06---C语言函数

    IOS学习笔记06---C语言函数 --------------------------------------------  qq交流群:创梦技术交流群:251572072              ...

  8. ES6学习笔记<三> 生成器函数与yield

    为什么要把这个内容拿出来单独做一篇学习笔记? 生成器函数比较重要,相对不是很容易理解,单独做一篇笔记详细聊一聊生成器函数. 标题为什么是生成器函数与yield? 生成器函数类似其他服务器端语音中的接口 ...

  9. OpenCV 学习笔记03 findContours函数

    opencv-python   4.0.1 1 函数释义 词义:发现轮廓! 从二进制图像中查找轮廓(Finds contours in a binary image):轮廓是形状分析和物体检测和识别的 ...

  10. canvas学习笔记、小函数整理

    http://bbs.csdn.net/topics/391493648 canvas实例分享 2016-3-16 http://bbs.csdn.net/topics/390582151 html5 ...

随机推荐

  1. 编译pano13的一些注意事项

    作者:朱金灿 来源:error C2037: "jmpbuf"的左侧部分指定未定义的结构/联合"png_struct_def"e:\src\Test\libpa ...

  2. 【26.34%】【codeforces 722A】Broken Clock

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  3. python implementation for Qt's QDataStream(看一下QDataStream的结构)

    #!/usr/bin/env python # -*- coding: utf- -*- from __future__ import print_function from __future__ i ...

  4. Android 比较两个时间段是否有交集或重复

    先看一个例图: 在金山<电池管家>应用中就有一个类似上图这样的功能—— 开启多个定时任务. 当开启另一个定时任务的时候,如果即将开启的这个定时任务的时间段与已经开启了的定时任务的时间段有交 ...

  5. jquery-3 jquery选择器

    jquery-3 jquery选择器 一.总结 一句话总结:选择器使用的时候可以结合参考手册,里面都已经详细归类好了.(多用才能熟啊) 1.$(:input).css({'color':'#98765 ...

  6. [NPM] Pipe data from one npm script to another

    In an effort to bypass saving temporary build files you can leverage piping and output redirection t ...

  7. 【hdu 2486】A simple stone game

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...

  8. JS前端图形化插件之利器Gojs组件(php中文网)

    JS前端图形化插件之利器Gojs组件(php中文网) 一.总结 一句话总结:php中文网我可以好好走一波 二.JS前端图形化插件之利器Gojs组件 参考: JS前端图形化插件之利器Gojs组件-js教 ...

  9. ionic新手教程第三课-在项目中使用requirejs分离controller文件和server文件

    继上篇教程中提到的,我们新建一个简单的tabs类型的Ionic项目. 依据文件夹文件我们知道,系统自己主动创建了一个controller文件和server文件,而且把全部的控制器和服务都写到这两个文件 ...

  10. 实际工程Quartz与Spring设计与实现一体化的热部署

    1.需求说明 主要负责项目任务调度.使用Quartz.以Spring为辅助. 如今有这样一个需求:我们不知道管理员想设定过多厂时间运行主任务,须要在配置文件定义.在配置好后须要马上运行.实现热部署. ...