c++中的虚函数是什么东西?
#include <iostream>
#include<string>
#include<vector>
using namespace std; class A
{
public:
void print()
{
cout<<"This is A"<<endl;
}
}; class B:public A
{
public:
void print()
{
cout<<"This is B"<<endl;
}
}; int main()
{ //为了在以后便于区分,我这段main()代码叫做main1
A a;
B b;
a.print();
b.print();
}
简单地说,那些被virtual关键字修饰的成员函数,就是虚函数。虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异而采用不同的策略。下面来看一段简单的代码
通过class A和class B的print()这个接口,可以看出这两个class因个体的差异而采用了不同的策略,
输出的结果也是我们预料中的,分别是This is A和This is B。但这是否真正做到了多态性呢?
No,多态还有个关键之处就是一切用指向基类的指针或引用来操作对象。那现在就把main()处的代码改一改。
#include <iostream>
#include<string>
#include<vector>
using namespace std; class A
{
public:
void print()
{
cout<<"This is A"<<endl;
}
}; class B:public A
{
public:
void print()
{
cout<<"This is B"<<endl;
}
}; int main()
{
A a;
B b;
A* p1=&a;
A* p2=&b;
p1->print();
p2->print();
}
运行一下看看结果,结果却是两个This is A。问题来了,p2明明指向的是class B的对象但却是调用的class A的print()函数,这不是我们所期望的结果,那么解决这个问题就需要用到虚函数
#include <iostream>
#include<string>
#include<vector>
using namespace std; class A
{
public:
virtual void print()
{
cout<<"This is A"<<endl;
}
}; class B:public A
{
public:
void print()
{
cout<<"This is B"<<endl;
}
}; int main()
{
A a;
B b;
a.print();
b.print();
} int main()
{ //main2
A a;
B b;
A* p1=&a;
B* p2=&b;
p1->print();
p2->print();
}
毫无疑问,class A的成员函数print()已经成了虚函数,那么class B的print()成了虚函数了吗?回答是Yes,
我们只需在把基类的成员函数设为virtual,其派生类的相应的函数也会自动变为虚函数。
所以,class B的print()也成了虚函数。那么对于在派生类的相应函数前是否需要用virtual关键字修饰,那就是你自己的问题了。
现在重新运行main2的代码,这样输出的结果就是This is A和This is B了。
现在来消化一下,我作个简单的总结,指向基类的指针在操作它的多态类对象时,会根据不同的类对象,
调用其相应的函数,这个函数就是虚函数。
c++中的虚函数是什么东西?的更多相关文章
- EC笔记,第二部分:9.不在构造、析构函数中调用虚函数
9.不在构造.析构函数中调用虚函数 1.在构造函数和析构函数中调用虚函数会产生什么结果呢? #; } 上述程序会产生什么样的输出呢? 你一定会以为会输出: cls2 make cls2 delete ...
- 关于在C#中构造函数中调用虚函数的问题
在C#中如果存在类的继承关系,应避免在构造函数中调用虚函数.这是由于C#的运行机制造成的,原因如下: 新建一个类实例时,C#会先初始化该类(对类变量赋值,并将函数记在函数表中),然后再初始化父类.构造 ...
- C++ 构造函数中调用虚函数
我们知道:C++中的多态使得可以根据对象的真实类型(动态类型)调用不同的虚函数.这种调用都是对象已经构建完成的情况.那如果在构造函数中调用虚函数,会怎么样呢? 有这么一段代码: class A { p ...
- 关于C++虚函数的一些东西
先上概念,C++的多态性:系统在运行时根据对象类型,来确定调用哪个重载的成员函数的能力. 多态性是通过虚函数实现的.成员函数之前加了virtual,即成为虚函数. 有虚成员函数的类,编译器在其每个对象 ...
- C++中的虚函数解析[The explanation for virtual function of CPlusPlus]
1.什么是虚函数? ...
- C++箴言:避免构造或析构函数中调用虚函数
如果你已经从另外一种语言如C#或者Java转向了C++,你会觉得,避免在类的构造函数或者析构函数中调用虚函数这一原则有点违背直觉.但是在C++中,违反这个原则会给你带来难以预料的后果和无尽的烦恼. 正 ...
- 读书笔记 effective c++ Item 9 绝不要在构造函数或者析构函数中调用虚函数
关于构造函数的一个违反直觉的行为 我会以重复标题开始:你不应该在构造或者析构的过程中调用虚函数,因为这些调用的结果会和你想的不一样.如果你同时是一个java或者c#程序员,那么请着重注意这个条款,因为 ...
- C#中的虚函数及继承关系
转载:http://blog.csdn.net/suncherrydream/article/details/8423991 若一个实例方法声明前带有virtual关键字,那么这个方法就是虚方法. 虚 ...
- C++进阶--构造函数和析构函数中的虚函数
//############################################################################ /* 任何时候都不要在构造函数或析构函数中 ...
随机推荐
- glib的安装(2)
一: glib库的路径: http://ftp.acc.umu.se/pub/GNOME/sources/glib/2.20/ 二: 下载glib库: wget http://ftp.acc. ...
- 直播:中国HBase技术社区第一届MeetUp
6月6日,由中国HBase技术社区组织,阿里云主办的中国第一届HBase Meetup将在北京举行,来自阿里.小米.滴滴.360等公司的各位大神会共同探讨HBase2.0的技术革新,HBase在国内各 ...
- YARN commands are invoked by the bin/yarn script.
Apache Hadoop 2.9.0 – YARN Commands http://hadoop.apache.org/docs/stable/hadoop-yarn/hadoop-yarn-sit ...
- java 相关博客
Intellij Idea 创建Web项目入门(一) SpringMVC 和 MyBatis 学习笔记,搭配示例,主要讲解一些基础的概念.用法和配置 包含框架有:SpringMVC.MyBaits.A ...
- MapReduce ChainMapper/ChainReducer
The ChainMapper class allows to use multiple Mapper classes within a single Map task. The ChainRedu ...
- 基于Delphi7 WebService 在Apache发布及Apache使用说明
基于Delphi7 WebService 在Apache 发布及Apache 使用说明 qq:394251165 前段时间,需要将基于Delphi7 WebService 发布在Apache, 很是苦 ...
- glibc CVE-2015-7547漏洞的分析和修复方法【转】
本文转载自:http://blog.csdn.net/tengxy_cloud/article/details/50764370 漏洞概述 glibc中处理DNS查询的代码中存在栈溢出漏洞,远端攻击者 ...
- nginx最简单的网站配置:单主机+静态文件
1.域名绑定主机:新建一个A记录,将www的子域名绑定到主机的ip上:2.主机的nginx设置监听端口,绑定域名,修改网站根目录路径和默认首选文件:/etc/nginx/conf.d 这个目录中新建一 ...
- java中io类型及成熟io框架
就io本身而言,概念上有5中模型:blocking I/O, nonblocking I/O, I/O multiplexing(select and poll), singal driven I/O ...
- jquery实现无限滚动瀑布流实现原理
现在类似于pinterest这类的表现效果很火,其实我比较中意的是他的布局效果,而不是那种瀑布流. 虽然我不是特别喜欢这种瀑布流的表现样式,但是还是写了几篇关于无限滚动瀑布流效果的文章,Infinit ...