[条款36]绝不重新定义继承而来的non-virtual函数
看下面的两个类的声明代码:
class B
{
public:
void mf();
//something to do
}; class D : public B
{
public:
void mf();
};
如果有下面的调用:
D x;
//第一种调用
B *pB = &x;
pB->mf();//调用B::mf
//第二种调用
D *pD = &x;
pD->mf();//调用D::mf
这两种调用的行为是不一样的,虽然从表面上看,两者都是通过对象x调用成员函数mf,凭借相同的对象。但是怎么就调用到了不同的函数呢。
造成这一两面性的原因是non-virtual函数都是静态绑定的。意思是,由于PB被声明为一个pointer-to-B,通过PB调用的non-virtual函数永远是B所定义的版本,即使PB指向了一个类型为“B派生的子类”
提示:
但是另一方面,virtual函数是动态绑定的,如果mf是一个virtual函数,不论是通过pB或者pD调用mf,都会导致调用D:mf,因为pB和pD真正指向的都是一个类型为D的对象。
所以问题就来了,如果在编程的时候,在class D中重新定义了继承自class B的non-virtual函数mf,D对象就可能展现出精神分裂的不一致行为。也就是说,当mf被调用的时候,任何一个D对象都可能表现出B或者D的行为。决定因素不在对象自身,而在于“指向该对象的指针”当初声明的类型。
提示:
References也会展现和指针难以理解的行径。
[条款36]绝不重新定义继承而来的non-virtual函数的更多相关文章
- 《effective C++》:条款36——绝不重新定义继承而来的非虚函数
(1)当派生类中重写了基类的非虚函数时,这个时候这个函数发生的是静态绑定 下面中的代码中: 定义一个基类B,基类定义了函数fcm,fcm是非虚的函数. 定义一个派生类D,派生类重新定义了fcm. 当用 ...
- 《effective C++》:条款37——绝不重新定义继承而来的缺省参数值
引子: 阿里的一道题: #include <IOSTREAM> using namespace std; class A{ public: ) { cout<<"a~ ...
- 【36】绝不重新定义继承而来的non-virtual方法
1.绝不重新定义继承而来的non-virtual方法,为什么? 首先想想,non-virtual方法是干什么的?也就是说,它的使用场景.父类的non-virtual方法,其实就是告诉子类,继承实现,子 ...
- 读书笔记 effective c++ Item 36 永远不要重新定义继承而来的非虚函数
1. 为什么不要重新定义继承而来的非虚函数——实际论证 假设我告诉你一个类D public继承类B,在类B中定义了一个public成员函数mf.Mf的参数和返回类型并不重要,所以假设它们都是void. ...
- [EffectiveC++]item37:绝不重新定义继承而来的缺省参数值
绝不重新定义继承而来的缺省参数值 静态类型 动态类型
- C++ 静态绑定与动态绑定------绝不重新定义继承而来的缺省参数
在了解静态绑定和动态绑定之前,先了解什么是对象的静态类型,什么是对象的动态类型. 对象的静态类型:对象在声明时采用的类型.是在编译器决定的. 对象的动态类型:目前所指对象的类型.是在运行期决定的. 动 ...
- Effective C++ -----条款36:绝不重新定义继承而来的non-virtual函数
绝对不要重新定义继承而来的non-virtual函数.
- 条款36:绝不重新定义继承而来的non-virtual函数(Never redefine an inherited non-virtual function)
NOTE: 1.绝对不要重新定义继承而来的non-virtual函数.
- 读书笔记_Effective_C++_条款三十七:绝不重新定义继承而来的缺省参数值
先看下面的例子: enum MyColor { RED, GREEN, BLUE, }; class Shape { public: ; }; class Rectangle: public Shap ...
随机推荐
- Android TextWatcher应用实例
(1)使用TextWathcer限制输入字符个数布局中EditText在android布局中经常用到,对EditText中输入的内容也经常需要进行限制,我们可以通过TextWatcher去观察输入框中 ...
- php保留小数格式的多种方法
php保留小数格式,定义小数格式,小数点,位数,小数位数: 方法一:(推荐)bcmul(1000.90,1,2);//两个数相乘1000.90*1, 保留两位小数点(无四舍五入)<返回strin ...
- js导出成excel
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- spring集成mongodb封装的简单的CRUD
1.什么是mongodb MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. mongoDB MongoDB是一个介 ...
- 张王李相亲应用if else
package hello; public class to { public static void main(String[]args){ int a =1,b=0; int c =1,d=0; ...
- jQuery中on()方法用法实例详解
这篇文章主要介绍了jQuery中on()方法用法,实例分析了on()方法的功能及各种常见的使用技巧,并对比分析了与bind(),live(),delegate()等方法的区别,需要的朋友可以参考下 本 ...
- SMACSS:一个关于CSS的最佳实践-1.Overview
什么是SMACSS? SMACSS(发音"smacks"),全称Scalable and Modular Architecture for CSS.顾名思义,SMACSS是一个可扩 ...
- C#隐藏桌面图标和任务栏
最近因为项目需要需要实现桌面图标和任务状态栏的隐藏功能,实现的方式很多,比如修改注册表值,调用windows API函数等.经过一番的查阅,这个功能暂时实现了,或许不是很好的方法,但是我预期的效果达到 ...
- BZOJ 1602: [Usaco2008 Oct]牧场行走( 最短路 )
一棵树..或许用LCA比较好吧...但是我懒...写了个dijkstra也过了.. ---------------------------------------------------------- ...
- BZOJ 1266: [AHOI2006]上学路线route(最短路+最小割)
第一问最短路.第二问,先把最短路的图建出来(边(u,v)满足d[s->u]+d[v->t]+d(u,v)==最短路径长度,就在图中,可以从源点和汇点分别跑一次最短路得到每个点到源点和汇点的 ...