C++技能重拾
0、虽然静态成员函数不存在this指针,但还是不能在一个class里声明同名同参的虚函数和静态成员函数。
1、vftable里一个虚函数表是一个指针
2、delete本质,调用析构函数同时释放内存
Object *o = new Object();
// use object
delete o; // which first calls the destructor (if any) on its argument and then returns the memory allocated by new back to the free store.
o = NULL;
3、classA *p = new classB;
delete p; //如果classB没有析构虚函数,则调用classA的析构函数
仔细想,也只能调用原生A的析构了!
4、基类部分在派生类部分之前被构造,当基类构造函数执行时派生类中的数据成员还没被初始化。如果基类构造函数中的虚函数调用被解析成调用派生类的虚函数,而派生类的虚函数中又访问到未初始化的派生类数据,将导致程序出现一些未定义行为和bug。
5、子类的同名静态或非静态函数会覆盖父类的!
6、如果一个虚函数被继承下来而没有改变,那么虚函数中指针实际指向为父类,蛋疼,注意!!!
7、虚函数重载时,子类修改了父类的缺省的参数值,那么将根据指针本身的类型来决定缺省参数的值
8、virtual关键字的作用就是提示编译器进行迟后联编,告诉连接过程:“我是个虚的,先不要连接我,等运行时再说吧”。
1) 先期联编或静态联编:在编译时就能进行函数联编称为先期联编或静态联编。
2) 迟后联编或动态联编:在运行时才能进行的联编称为迟后联编或动态联编。
9、虚函数的原理:当编译器遇到virtual后,会为所在的类构造一个表和一个指针,那个表叫做vtbl,每个类都有自己的vtbl,vtbl的作用就是保存自己类中虚函数的地址,我们可以把vtbl形象地看成一个数组,这个数组的每个元素存放的就是虚函数的地址.指针叫做vptr,指向那个表。而这个指针保存在相应的对象当中,也就是说只有创建了对象以后才能找到相应虚函数的地址。
为确保运行时的多态定义的基类与派生类的虚函数不仅函数名要相同,其返回值及参数都必须相同,否则即使加上了virtual,系统也不进行迟后联编。
10、运算符重载的原则
这样一看,运算符重载还是蛮简单的嘛,实际上运算符重载也是要遵循一些原则的:
1.C++中只能对已有的C++运算符进行重载,不允许用户自己定义新的运算符。
2.C++中绝大部分的运算符可重载,除了成员访问运算符.,作用域运算符::,长度运算符sizeof以及条件运算符?:。
3.运算符重载后不能改变运算符的操作对象(操作数)的个数。如:"+"是实现两个操作数的运算符,重载后仍然为双目运算符。
4.重载不能改变运算符原有的优先级和原有的结合性。
6.运算符重载不能全部是C++中预定义的基本数据,这样做的目的是为了防止用户修改用于基本类型数据的运算符性质。
11、重载函数的定义:在相同的声明域中的函数名相同的,而参数表不同的,即通过函数的参数表而唯一标识并且来区分函数的一种特殊的函数。
12、为了估计哪个重载函数最适合,需要依次按照下列规则来判断:
精确匹配:参数匹配而不做转换,或者只是做微不足道的转换,如数组名到指针、函数名到指向函数的指针、T到const T;
提升匹配:即整数提升(如bool 到 int、char到int、short 到int),float到double
使用标准转换匹配:如int 到double、double到int、double到long double、Derived*到Base*、T*到void*、int到unsigned int;
使用用户自定义匹配;
使用省略号匹配:类似printf中省略号参数
如果在最高层有多个匹配函数找到,调用将被拒绝(因为有歧义、模凌两可)。看下面的例子:
void print(int);
void print(const char*);
void print(double);
void print(long);
void print(char);
void h(char c,int i,short s, float f)
{
print(c);//精确匹配,调用print(char)
print(i);//精确匹配,调用print(int)
print(s);//整数提升,调用print(int)
print(f);//float到double的提升,调用print(double)
print('a');//精确匹配,调用print(char)
print(49);//精确匹配,调用print(int)
print(0);//精确匹配,调用print(int)
print("a");//精确匹配,调用print(const char*)
}
C++技能重拾的更多相关文章
- C++技能重拾2
13.类成员函数重载:局部同名函数将隐藏而不是重载全局声明,不引入父类名字空间时子类的同名函数不会和父类的构成重载,静态成员函数可以和非静态成员函数构成重载.本质是重载函数的定义是在相同的声明域里!! ...
- CSS魔法堂:重拾Border之——更广阔的遐想
前言 当CSS3推出border-radius属性时我们是那么欣喜若狂啊,一想到终于不用再添加额外元素来模拟圆角了,但发现border-radius还分水平半径和垂直半径,然后又发现border-t ...
- CSS魔法堂:重拾Border之——不仅仅是圆角
前言 当CSS3推出border-radius属性时我们是那么欣喜若狂啊,一想到终于不用再添加额外元素来模拟圆角了,但发现border-radius还分水平半径和垂直半径,然后又发现border-t ...
- CSS魔法堂:重拾Border之——图片作边框
前言 当CSS3推出border-radius属性时我们是那么欣喜若狂啊,一想到终于不用再添加额外元素来模拟圆角了,但发现border-radius还分水平半径和垂直半径,然后又发现border-t ...
- CSS魔法堂:重拾Border之——解构Border
前言 当CSS3推出border-radius属性时我们是那么欣喜若狂啊,一想到终于不用再添加额外元素来模拟圆角了,但发现border-radius还分水平半径和垂直半径,然后又发现border-t ...
- 重拾Blog
上个月是我入职现在的公司三周年的月份,所以又续订了五年的合同,最近有一些思考,也不知道这个五年能否还会一直在这个公司工作. 一切随缘吧. 闲适有毒,忙碌的时光总是过的很快,自从加入这个公司以来,日常的 ...
- [linux]重拾linux
起因 因为想重拾起linux,同时需要用docker起几个镜像,用来学习网络知识.本来想直接去阿里云上买,后来一想自己机器上,起一个linux是个不错的选择,毕竟不花钱! 还可以用来做本地测试,学习使 ...
- 重拾qt
最近公司又接了一个煤矿的项目,要写个小程序摘取数据,我是公司唯一c++程序员,本来搞ios搞好好的,现在又得重拾半年没摸得qt了.呵呵...呵呵呵. 这里只记录这次小程序的一些小的总结吧.. 1.中文 ...
- 重拾linux
重拾linux 起因 因为想重拾起linux,同时需要用docker起几个镜像,用来学习网络知识.本来想直接去阿里云上买,后来一想自己机器上,起一个linux是个不错的选择,毕竟不花钱! 还可以用来做 ...
随机推荐
- 2019“嘉韦思”杯RSA256题目wp
首先我们从网站下载了一个压缩包,解压出来一看里面有2个文件 首先我们先打开fllllllag康康,结果发现是一串乱码,这时候第一反应就是,文件被加密了,再看fllllllag下面的gy.key文件,更 ...
- 权限管理,pymysql模块
权限管理 权限管理重点 MySQL 默认有个root用户,但是这个用户权限太大,一般只在管理数据库时候才用.如果在项目中要连接 MySQL 数据库,则建议新建一个权限较小的用户来连接. 在 MySQL ...
- hbase读写流程分析
前言 最近被大佬问到一个问题,hbase查询数据在最坏的场景下需要进行几次rpc,当时就懵了..下面主要对client端代码进行分析.阅读文章和看源码更配~ 读数据 流程总览 1. 从zookeepe ...
- HBase底层存储原理——我靠,和cassandra本质上没有区别啊!都是kv 列存储,只是一个是p2p另一个是集中式而已!
理解HBase(一个开源的Google的BigTable实际应用)最大的困难是HBase的数据结构概念究竟是什么?首先HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库.另一个不 ...
- 如何每日增量加载数据到Hive分区表
如何每日增量加载数据到Hive分区表 hadoop hive shell crontab 加载数据 数据加载到Hive分区表(两个分区,日期(20160316)和小时(10))中 每日加载前一天的日志 ...
- 微信网页跳转页面常见bug处理
微信网页跳转页面常见bug处理 1.不要直接用a链接直接跳转 2.url后加上时间戳 function gohome() { window.location.href = "../home/ ...
- illumina support
http://support.illumina.com/help/BaseSpace_App_WGS_BWA_help/Content/Vault/Informatics/Sequencing_Ana ...
- Linux——用户管理简单学习笔记(二)
其实如果我们了解了Linux中用户管理的配置文件之后,完全可以手工管理用户: 添加用户: useradd 设置选项 用户名 -D 查看缺省参数 u:UID g:缺省所属用户组GID G:指定用户所属多 ...
- 转载:oracle RAC集群启动和关闭
http://www.cnblogs.com/yhfssp/p/8184761.html oracle 11G RAC集群启动和关闭: 1.停止数据库 $srvctl stop database –d ...
- Codefores 835C-Star sky
835C-Star sky 思路:dp,预处理一下c+1层前缀和. 代码: #include<bits/stdc++.h> using namespace std; #define ll ...