C++学习笔记26,虚函数
在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,虚函数的更多相关文章
- 学习笔记---C++虚函数,纯虚函数
1 .虚函数 假设people是man的父类,people类和man类都定义了实函数walk() people* p = new man(); p->walk(); 这里P执行的是people类 ...
- C++学习笔记--从虚函数说开去
虚函数与纯虚函数: 虚函数:在某基类中声明为virtual并在一个或多个派生类中被重新定义的成员函数,virtual 函数返回类型 函数名(参数表){函数体;} ,实现多态性,通过指向派生类的基类 ...
- C++学习笔记27,虚函数作品
C++它指定虚函数的行为,但实现的作者编译器. 通常,编译器处理虚函数的方法是给每个对象加入一个隐藏成员.隐藏成员中保存了一个指向函数地址数组的指针. 这个数组称为虚函数表(virtual funct ...
- IOS学习笔记07---C语言函数-printf函数
IOS学习笔记07---C语言函数-printf函数 0 7.C语言5-printf函数 ------------------------- ----------------------------- ...
- Typescript 学习笔记三:函数
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- Python学习笔记之常用函数及说明
Python学习笔记之常用函数及说明 俗话说"好记性不如烂笔头",老祖宗们几千年总结出来的东西还是有些道理的,所以,常用的东西也要记下来,不记不知道,一记吓一跳,乖乖,函数咋这么多 ...
- IOS学习笔记06---C语言函数
IOS学习笔记06---C语言函数 -------------------------------------------- qq交流群:创梦技术交流群:251572072 ...
- ES6学习笔记<三> 生成器函数与yield
为什么要把这个内容拿出来单独做一篇学习笔记? 生成器函数比较重要,相对不是很容易理解,单独做一篇笔记详细聊一聊生成器函数. 标题为什么是生成器函数与yield? 生成器函数类似其他服务器端语音中的接口 ...
- OpenCV 学习笔记03 findContours函数
opencv-python 4.0.1 1 函数释义 词义:发现轮廓! 从二进制图像中查找轮廓(Finds contours in a binary image):轮廓是形状分析和物体检测和识别的 ...
- canvas学习笔记、小函数整理
http://bbs.csdn.net/topics/391493648 canvas实例分享 2016-3-16 http://bbs.csdn.net/topics/390582151 html5 ...
随机推荐
- LDR: LdrpWalkImportDescriptor() failed to probe C:\WINDOWS\system32\opencv_core243d.dll for its manifest, ntstatus 0xc0150002
LDR: LdrpWalkImportDescriptor() failed to probe C:\WINDOWS\system32\opencv_core243d.dll for its mani ...
- [Swift] Storyboard outlet and action
To programmaictlly change the content of app, we need to contect storyboard to a view controller. To ...
- 《Java设计模式》之抽象工厂模式
场景问题 举个生活中常见的样例--组装电脑.我们在组装电脑的时候.通常须要选择一系列的配件,比方CPU.硬盘.内存.主板.电源.机箱等. 为讨论使用简单点.仅仅考虑选择CPU和主板的问题. 其实,在选 ...
- phpstorm 2018本地激活
这是简书上找到的,害怕以后找不到,记录一下网址为https://www.jianshu.com/p/133af2e4fe3f
- IIS最大并发连接数 = 队列长度 + IIS最大并发工作线程数
深入理解IIS的多线程工作机制 首先让我们来看看IIS里面的这2个数字:最大并发连接数,队列长度.先说这2个数字在哪里看. 最大并发连接数:在IIS中选中一个网站,右键网站名称,在右键菜单中找到并 ...
- [React] Update State in React with Ramda's Evolve
In this lesson we'll take a stateful React component and look at how we can refactor our setState ca ...
- HDU 1243 反恐训练营 (动态规划求最长公共子序列)
反恐训练营 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- jquery平滑滚动页面
滚动到顶部 $('.scroll_top').click(function(){$('html,body').animate({scrollTop: '0px'}, 800);}); 滚动到指定位置 ...
- [Git] Use git add --patch for better commit history and mitigating bugs
Let's split our changes into separate commits. We'll be able to check over our changes before stagin ...
- js进阶 9-12 如何将数组的信息添加到下拉列表
js进阶 9-12 如何将数组的信息添加到下拉列表 一.总结 一句话总结:创建出select的option,然后selectElement的add方法加进 selectElement 即可 1.创建出 ...