在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. [Docker] Prune Old Unused Docker Containers and Images

    In this lesson, we will look at docker container prune to remove old docker containers. We can also ...

  2. 我眼中的c++编程总结-20150602

    断断续续的学习了非常多东西,有51.Avr.ARM.PLC.C\C++.C#.TB.MC.mql4.linux....等等,近乎填鸭或者囫囵吞枣的.甚至饿狼般的扑到里面,慢慢的积累和理解中,非常多知识 ...

  3. Strut2与Hibernate的一个web分页功能

    代码没有进行过多的封装,可能看起来有点action代码部分,hibernate在这里只起到了一个查询记录集的作用. import java.util.ArrayList; import java.ut ...

  4. Django表单上传

    任务描述:实现表单提交(上传文件) 1.项目目录: 2.源代码: regist.html <!DOCTYPE html> <html lang="en"> ...

  5. 诊断并解决CentOS SSH连接慢的方法

    诊断并解决CentOS SSH连接慢的方法: http://os.51cto.com/art/201507/484743.htm

  6. [NPM] Use package.json variables in npm scripts

    In this lesson we will show that you can leverage values that you already have provided in your pack ...

  7. 第三十一天 慵懒的投射在JDBC上的暖阳 —Hibernate的使用(四)

    6月19日,小雨."黄梅时节家家雨.青草池塘处处蛙.有约不来过夜半,闲敲棋子落灯花." 面向对象无限包容的个性,给对SQL和数据库一窍不通的澳大利亚人Gavin King创造了极大 ...

  8. 关闭 You need to use a Theme.AppCompat theme (or descendant) with this activity解决方法

    当我的MainActivity继承自v7包中的ActionBarActivity或者AppCompatActivity时,如果在style.xml文件中指定MainActivity所使用的样式如下: ...

  9. 7个在线学习C++编程的最佳途径

    7个在线学习C++编程的最佳途径 jopen 2012-09-27 15:51:13 • 发布 摘要:C++是一种静态数据类型检查的.支持多重编程范式的通用程序设计语言.它支持过程化程序设计.数据抽象 ...

  10. C#中类和结构体的区别

    结构体和类同样能够定义字段,方法和构造函数,都能实例化对象,这样看来结构体和类的功能好像是一样的了,但是他们在数据的存储上是不一样的(以下摘录): C#结构体和类的区别问题:在C#编程语言中,类属于引 ...