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++进阶--构造函数和析构函数中的虚函数
//############################################################################ /* 任何时候都不要在构造函数或析构函数中 ...
随机推荐
- DBExecutor android 数据库框架
https://github.com/eltld/DBExecutor android 数据库框架,sqlite database
- Linux编程---进程通信
Linux的通信方式主要有分类有以下几种: -匿名管道和FIFO有名管道 -消息队列,信号量和共享存储 -套接字 对于套接字的进程通信,我就留在套接字的文章中再写了. 一.管道 管道是最古老的进程通信 ...
- Codeforces 3A-Shortest path of the king(BFS打印路径)
A. Shortest path of the king time limit per test 1 second memory limit per test 64 megabytes input s ...
- Bean定义并注册到spring
1.XML配置文件 2.Annotation注解 3.Java Code 配置方式 BeanDefinitionRegistryPostProcessor
- Serialization and deserialization are bottlenecks in parallel and distributed computing, especially in machine learning applications with large objects and large quantities of data.
Serialization and deserialization are bottlenecks in parallel and distributed computing, especially ...
- mysql 免安装配置问题
摘要: MySQL是一个小型关系型数据库管理系统,MySQL被广泛地应用在Internet上的中小型网站中.由于其体积小.速度快.总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网站总体 ...
- 20170221 SE03 打包请求
请求处理:SE03 只会有其中两三个功能,还需要学习. 请求打包,是传输请求时候常用的一种方法. 步骤如下: 注意点:1.打包请求一定仔细检查,不要遗漏 如果请求不多,分开传是更好 ...
- DDD战略设计相关核心概念的理解
前言 本文想再讨论一下关于领域.业务.业务模型.解决方案.BC.领域模型.微服务这些概念的含义和关系.初衷是我发现现在DDD领域建模以及解决方案落地过程中,常常对这些概念理解不清楚或者有歧义,导致我们 ...
- 从源码理解 ThreadLocal
为每个线程保存各自的拷贝,可以通过在Thread类中定义一个成员变量来保存每个线程值,这样也是线程安全的. 通过定义一个成员变量 sn 来实现,这里并没有使用ThreadLocal类来实现: publ ...
- 使用proc接口例子【转】
本文转载自:http://blog.csdn.net/mike8825/article/details/52434666 版权声明:本文为博主原创文章,未经博主允许不得转载. 在上一篇的使用sys接口 ...