C++ 的那些坑 (Day 2)
虚函数调用的例外
我们知道在通过基类的指针或者引用调用某个对象的函数时,如果这个对象是一个派生类而且该方法是一个虚方法那么一般情况下就会调用派生类的虚方法实现。这个过程是C++的多态。然而这之中有些例外,如果当我们在基类的构造函数或者析构函数中调用相关的虚方法时,他们被绑定到本类层级里的方法实现,而不会去动态的调用子类中的方法实现。如下面这个例子测试了析构函数中调用虚函数的情况
class Water {
public:
virtual void print(const string& msg) {
cout<<"Water:"<<msg<<endl;
}
virtual ~Water() {
print("ran out of water");
}
};
class Rain : public Water {
public:
virtual void print(const string& msg) {
cout<<"Rain:"<<msg<<endl;
}
virtual ~Rain() {
print("rain stop");
}
};
int main() {
{
shared_ptr<Rain> rain{new Rain};
}
return 0;
}
上述程序运行输出:
Rain:rain stop
Water:ran out of water
C++ Primer给出的解释大概意思是每个构造函数负责构造初始化本类成员,如果允许在构造函数内部使用虚函数那边子类的函数执行时器数据成员或者相关的状态都没初始化运行结果不能确定,同样析构时由于析构是从子类向基类逐渐进行,那在基类析构函数中调用虚函数会使得(子类中的)虚函数实现使用一些(子类)已经销毁的数据成员或者状态,造成不确定的后果。所以C++中就这么规定了,构造函数和析构函数中的虚函数调用其实在编译其就已经绑定了。
虚函数默认参数
虚函数绑定虽然是在运行时进行的,但是默认参数则在编译期已经决定。
class Base {
public:
virtual void print(int value = 1) {
cout<<value<<endl;
}
};
class Derived : public Base {
public:
virtual void print(int value = 2) {
cout<<value<<endl;
}
};
int main() {
{
shared_ptr<Base> b{new Derived};
b->print();
}
return 0;
}
程序运行输出:
1
C++ 的那些坑 (Day 2)的更多相关文章
- 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑
阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...
- 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例
前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...
- Spark踩坑记——Spark Streaming+Kafka
[TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...
- 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
- 踩石行动:ViewPager无限轮播的坑
2016-6-19 前言 View轮播效果在app中很常见,一想到左右滑动的效果就很容易想到使用ViewPager来实现.对于像我们常说的banner这样的效果,具备无限滑动的功能是可以用ViewPa ...
- 为C# as 类型转换及Assembly.LoadFrom埋坑!
背景: 不久前,我发布了一个调试工具:发布:.NET开发人员必备的可视化调试工具(你值的拥有) 效果是这样的: 之后,有小部分用户反映,工具用不了(没反应或有异常)~~~ 然后,建议小部分用户换个电脑 ...
- 首个threejs项目-前端填坑指南
第一次使用threejs到实际项目中,开始的时候心情有点小激动,毕竟是第一次嘛,然而做着做着就感受到这玩意水好深,满满的都是坑,填都填不过来.经过老板20天惨无人道的摧残,终于小有成就. 因为第一次搞 ...
- dll文件32位64位检测工具以及Windows文件夹SysWow64的坑
自从操作系统升级到64位以后,就要不断的需要面对32位.64位的问题.相信有很多人并不是很清楚32位程序与64位程序的区别,以及Program Files (x86),Program Files的区别 ...
- 关于微软HttpClient使用,避免踩坑
最近公司对于WebApi的场景使用也越来越加大了,随之而来就是Api的客户端工具我们使用哪个?我们最常用的估计就是HttpClient,在微软类库中命名空间地址:System.Net.Http,是一个 ...
- iOS审核这些坑,腾讯游戏也踩过
作者:Jamie,专项技术测试工程师,在iOS预审和ASO优化领域从事专项测试相关工作,为腾讯游戏近100个产品提供专项服务. WeTest 导读 在App上架苹果应用商店的过程中,相信大多数iOS开 ...
随机推荐
- 常用Yum镜像源
163网易的yum源 wget http://mirrors.163.com/.help/CentOS6-Base-163.repo sohu的yum源 wget http://mirrors.soh ...
- 27_网络编程-初识socket
一.C/S B/S 架构 1.定义 (1)C/S结构,即Client/Server(客户机/服务器)结构,是大家熟知的软件系统体系结构,通过将任务合理分配到Cl ...
- Codeforces 1058 D. Vasya and Triangle(分解因子)
题目:http://codeforces.com/contest/1058/problem/D 题意:有一个大小为N*M的矩阵内,构造一个三角形,使面积为(n*m)/k.若存在输出三个顶点(整数). ...
- 组件基础(参数校验和动态组件、v-once)—Vue学习笔记
最最最后一点关于组件传值的问题. 提醒:本篇内容请使用Vue.js开发版!(附带完成的警告和提示) 1.组件的参数校验 父组件向子组件传值,子组件可以决定传值的一些限制. 比如,子组件指向接收Stri ...
- JS常用工具函数(持续记录)
1.设置获取cookie //方式1 //设置cookie function SetCookie(name, value)//两个参数,一个是cookie的名字,一个是值 { var Days = 3 ...
- (转)python类:magic魔术方法
原文:https://blog.csdn.net/pipisorry/article/details/50708812 版权声明:本文为博主皮皮http://blog.csdn.net/pipisor ...
- ThreadLocal是否会引发内存泄露的分析 good
这篇文章,主要解决一下疑惑: 1. ThreadLocal.ThreadLocalMap中提到的弱引用,弱引用究竟会不会被回收? 2. 弱引用什么情况下回收? 3. JAVA的ThreadLocal和 ...
- C# 自定义类型通过实现IFormattable接口,来输出指定的格式和语言文化的字符串(例:DateTime)
常规的调用ToString()方法,存在两个问题. (1).调用者无法控制字符串的格式 (2).调用者不能方便的选择一种特定的语言文化来格式化字符串. 在开发一些国际化的应用时,应用程序需要调用与当前 ...
- vim常用命令总结(转)
vim常用命令 -------------------------------------------------------------------------------------------- ...
- C#基础篇二变量与变量类型
说到数据类型,先把基本的数据类型拿出来 byte 0 到 255 无符号 8 位整数sbyte -128 到 127 有符号 8 位整数short -32,768 到 32,767 有符号 16 位整 ...