在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. 【u246】卫星照片

    Time Limit: 1 second Memory Limit: 64 MB [问题描述] 农夫 John 正在研究他的农场的卫星照片.照片为一个R (1<= R <= 75) 行C ...

  2. [AngularJS] Write a simple Redux store in AngularJS app

    The first things we need to do is create a reducer: /** * CONSTANT * @type {string} */ export const ...

  3. thinkphp 3.2,引入第三方类库的粗略记录

    首先用第三方类库我是放到vendor里面的 根目录\ThinkPHP\Library\Vendor\Wxphp 例如创建了一个Wxphp文件夹,里面有个php文件叫做     zll.php    文 ...

  4. 【42.38%】【BZOJ 3196】二逼平衡树

    Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1363 Solved: 579 [Submit][Status][Discuss] Descripti ...

  5. [Recompose] Lock Props using Recompose -- withProps

    Learn how to use the ‘withProps’ higher order component to pre-fill a prop, unable to be overridden. ...

  6. Android Widget和悬浮窗 原理

    1.简单介绍 Android widget是桌面插件,在android系统应用开发层面有特殊用途. AppWidget是把一个进程的控件嵌入到别外一个进程的窗口里的一种方法.悬浮窗的效果与Widget ...

  7. jquery修改获取radio的选中项

    <input id="txtBeginDate" onclick="$('#divDate').css({'top':$('#txtBeginDate').offs ...

  8. Java的面向AOP编程

    一. 引言 AOP(Aspect-Oriented Programming,面向切面的编程),是一种新型的编程范式,主张关注软件流程中的一个切面,将相同功能的代码整合打包在一起,减少系统的耦合性,增强 ...

  9. C++ 计算任意两个日期之间的天数

    C++写的一个计算两个日期之间天数的小程序: #include <Windows.h> #include <stdio.h> struct tagDate { int year ...

  10. android studio 2.2 使用cmake编译NDK

    Android studio 2.2 已经进入beta版本,新功能添加众多,NDK编程也得到了简化.官方博客介绍.本文介绍如何使用新版android studio调用 c++代码,为了超级通俗易懂,例 ...