深入理解C++11 阅读笔记
二 保证稳定性和兼容性
保持与C99兼容
预定义宏
C99语言标准增加的一些预定义宏,C++11同样增加了对这些宏的支持
- __func__预定义标识符
功能是返回所在函数的名字,在C++11中,标准甚至允许其使用在类或者结构体中
- _Pragma操作符
C/C++标准中,#pragma是一条预处理的指令,用来向编译器传达语言标准以外的一些信息,例如#pragma once 表示该头文件应该只被编译一次
在C++11中,标准定义了与预处理指令#pragma功能相同的操作符_Pragma,例如 _Pragma ("once");
- 变长参数的宏定义以及__VA_ARGS__
在C99标准中,变长参数的宏定义是指在宏定义中参数列表的最后一个参数为省略号,而预定义宏__VA_ARGS__则可以在宏定义的实现部分替换省略号所代表的字符串
#define PR(...) printf(__VA_ARGS__)
- 宽窄字符串的连接
C++标准中,将窄字符串(char)转换成宽字符串(wchar_t)是未定义的行为
在C++11标准中,在将窄字符串和宽字符串进行连接时,会将窄字符串转换成宽字符串,然后再与宽字符串进行连接
宏__cpluscplus__
C与C++混用头文件的典型用法
1 #ifidef __cplusplus
2 extern "C" {
3 #endif
4 // 一些代码
5 #ifdef __cplusplus
6 }
7 #endif
C++11中 __cplusplus 被定义为 201103L 可以用来检测是否支持C++11
#if __cplusplus < 201103L
#error "should use C++11 implemention " //预编译指令
#endif
静态断言
断言就是将一个返回值总是需要为真的判别式放在语句中,用于排除在设计的逻辑上不应该产生的情况,以迫使程序在发生异常时,退出,从而避免程序陷入逻辑的混乱
头文件assert.h定义的宏受NDEBUG的影响.如果预程序在处理这个头文件时已经定义了NDEBUG,assert宏的内容就定义为空,这意味着assert宏不在起作用.所以,可以在最终
发布程序的时候可以使用-DNDEBUG关闭断言功能或者把#define NDEBUG加到每个源文件中,但这条语句必须放在#include <assert.h>之前.
- 静态断言与static_assert
assert运行时断言
C++11标准中,引入了static_assert断言,解决编译时断言
static_assert(常量表达式,提示字符串)。
如果第一个参数常量表达式的值为真(true或者非零值),那么static_assert不做任何事情,就像它不存在一样,否则会产生一条编译错误,错误位置就是该static_assert语句所在行,错误提示就是第二个参数提示字符串。
noexcept修饰符与noexcept操作符
C++98中,动态异常声明throw(int,double), C++11中被弃用
1 void except_func() throw(int, double){ ... }
表示函数不会抛出异常的动态异常声明throw()也被新的noexcept异常声明所取代
- noexcept
void except_func() noexcept; 表示不抛出异常
void except_func() noexcept(常量表达式);表达式为true不会抛出异常;flase抛出异常
快速初始化成员变量
在C++98中,支持了在类声明中使用等号“=”加初始值的方式,来初始化类中静态成员常量。这种方式我们也称之为”就地“声明。
C++11标准允许,对非静态成员变量初始化有多种形式
- C++11中允许使用等号=或者花括号{}进行就地的非静态成员变量初始化
- C++11中,保留了初始化列表
非静态成员的sizeof
c++11中,允许对非静态成员变量使用sizeof,而 C++98 标准只允许静态成员变量,或者对象的实例才能对其成员进行sizeof操作
1 struct People {
2 public:
3 int hand;
4 static People * all;
5 };
6
7 int main()
8 {
9 People p;
10 cout << sizeof(p.hand) << endl; // C++98中通过, C++11中通过
11 cout << sizeof(People::all) << endl; // C++98中通过, C++11中通过
12 cout << sizeof(People::hand) << endl; // C++98中错误, C++11中通过
13 }
扩展的friend语法
- C++11中,声明一个类为另外一个类的友元时,不再需要使用class关键字
- c++11中, 别名同样可行
- C++11中, 可以为类模板声明友元
final/override控制
- final 派生类不可覆盖它所修饰的虚函数
- override 必须重写其基类中的同名函数,否则代码将无法通过编译
模板函数的默认模板参数
外部模板
局部和匿名类型作模板实参
三 通用为本,专用为末
继承构造函数
隐藏:类具有可派生性,派生类可以自动获得基类的成员变量和接口(虚函数和纯虚函数,这里我们指的都是public派生)。不过基类的非虚函数则无法再被派生类使用了。
这条规则对于类中最为特别的构造函数也不例外,如果派生类要使用基类的构造函数,通常需要在构造函数中显式声明
- C++中,使用using声明,实现构造函数透传到派生类
1 struct Base{
2 void f(double i) {}
3 };
4 struct Derived : Base{
5 using Base::f;
6 void f(int i){}
7 };
8
9 int main(){
10 Base b;
11 b.f(4.5); // Base:4.5
12
13 Derived d;
14 d.f(4.5); // Base:4.5
15 }
注:
如果积累的构造函数被声明为私有成员函数,或者派生类是从基类中虚继承来的,那么就不能再派生类中声明继承构造函数,
如果使用继承构造函数,编译器就不会载为派生类生成默认构造函数
委派构造函数
1 class Info {
2 public:
3 Info() : Info(1) {} // 委派构造函数
4 Info(int i) : Info(i, 'a') {} // 既是目标构造函数,也是委托构造函数,是一种链状委托构造
5 Info(char e) : Info(1, e) {}
6 private:
7 Info(int i, char e) : type(i), name (e) {} // 目标构造函数
8 int type;
9 char name;
注:
1、C++中,构造函数不能同时委派和初始化成员,如果委派构造函数要为成员变量赋值,初始化代码必须放在函数体内
2、构造函数比较多时可能拥有不止一个委派构造函数,而目标构造函数很可能也是委派构造函数,这样一来可能在委派构造函数中形成链状的委派构造关系
有一点要注意不能形成委托环
深入理解C++11 阅读笔记的更多相关文章
- 深入理解 C 指针阅读笔记 -- 第六章
Chapter6.h #ifndef __CHAPTER_6_ #define __CHAPTER_6_ /*<深入理解C指针>学习笔记 -- 第六章*/ typedef struct _ ...
- 深入理解 C 指针阅读笔记 -- 第二章
Chapter2.h #ifndef __CHAPTER_2_ #define __CHAPTER_2_ /*<深入理解C指针>学习笔记 -- 第二章*/ /* 内存泄露的两种形式 1.忘 ...
- 深入理解 C 指针阅读笔记 -- 第五章
Chapter5.h #ifndef __CHAPTER_5_ #define __CHAPTER_5_ /*<深入理解C指针>学习笔记 -- 第五章*/ /*不应该改动的字符串就应该用 ...
- 深入理解Java 虚拟机阅读笔记(一)
1.程序计数器- 占用空间:较小 作用:字节码行号指示器 作用详情:指示指令执行,如(字节码的执行,分支,循环,跳转,异常处理,线程恢复) 特点:线程私有(每个计数器独立计算,上下文相互独立). 2. ...
- 深入理解Java虚拟机--阅读笔记三
垃圾收集器 手机算法是内存回收的方法论,垃圾收集器是内存回收的具体实现. 并行:指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态 并发:值用户线程与垃圾收集线程同时执行(但并不一定是并行的) ...
- 深入理解Java虚拟机--阅读笔记二
垃圾收集器与内存分配策略 一.判断对象是否已死 1.垃圾收集器在对堆进行回收前,要先判断对象是否已死.而判断的算法有引用计数算法和可达性分析算法: 2.引用计数算法是给对象添加引用计数器,有地方引用就 ...
- 深入理解Java虚拟机--阅读笔记一
Java内存区域 一.java运行时数据区域 1. 程序计数器:程序计数器占据的内存空间较小,是当前运行线程执行的字节码的计数:分支.循环.跳转.异常处理.线程恢复等都要依赖技术器来对执行的字节码进行 ...
- 深入理解JAVA虚拟机阅读笔记6——线程安全与锁优化
线程安全:如果一个对象可以安全的被多个线程同时使用,那它就是线程安全的. 一.Java中的线程安全 1.不可变 不可变的对象一定是线程安全的.String.枚举类型.java.lang.Number的 ...
- 深入理解JAVA虚拟机阅读笔记5——Java内存模型与线程
Java内存模型是定义线程共享的变量的访问规则(实例字段.静态字段和构成数组对象的元素),但不包括线程私有的局部变量和方法参数. 1.主内存与工作内存 Java内存模型规定,所有的变量都必须存储在主内 ...
随机推荐
- Nextcloud 使用教程
一.简介 Nextcloud是一个网盘式文件管理系统,多用户权限管理,多客户端,使用简单.可在浏览器中运行,也可下客户端,不论使用哪种方式运行,使用教程都是一样的. 只是在客户端中运行时能及时收到相应 ...
- 通过Maven打jar包&运行
运行命令:java -jar [包名] https://www.cnblogs.com/jinjiyese153/p/9374015.html
- Go timer 是如何被调度的?
hi,大家好,我是 haohongfan. 本篇文章剖析下 Go 定时器的相关内容.定时器不管是业务开发,还是基础架构开发,都是绕不过去的存在,由此可见定时器的重要程度. 我们不管用 NewTimer ...
- 前端工具 | JS编译器 Brace 使用教程
前言 开发人员一般是在电脑上面安装了IDE完成日常的开发任务,因为项目业务需求,用户想要在线写JS脚本,纯粹的字符串,很"费用户".那就需要一个在线JS编译器,需要轻量级,好用,语 ...
- 自动机器学习(AutoML)
自动机器学习(AutoML) 不再需要苦恼于学习各种机器学习的算法 目录: 一.为什么需要自动机器学习 二.超参数优化 Hyper-parameter Optimization 三.元学习 Meta ...
- MySQL 主从复制&读写分离 简介
1. 读写分离&读写分离 简介 主从同步延迟 分配机制 解决单点故障 总结 2. 主从复制&读写分离 搭建 搭建主从复制(双主) 搭建读写分离 1. 读写分离&读写分离 简介 ...
- (3)虚拟Web主机
虚拟Web主机 作用:让一台Web服务器,提供多个页面 搭建方式: 1.基于域名的虚拟Web 2.基于端口的虚拟Web 3.基于IP地址的虚拟Web ######################### ...
- 【渗透实战】记一次艰难的内网漫游第四期_蹭我WIFI?看我如何利用组合拳日进蹭网者内网
/文章作者:Kali_MG1937 CSDN博客ID:ALDYS4 QQ:3496925334/ 内网漫游系列第三期:[渗透实战]记一次艰难的内网漫游第三期_我是如何利用APT攻击拿到内网最高权限的 ...
- Redis 面试题 - 收藏版 (持续更新、吐血推荐)
文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...
- 「模拟8.19 A嚎叫..(set) B主仆..(DFS) C征程..(DP+堆优化)」
为啥这一套题目背景感到很熟悉. T1 嚎叫响彻在贪婪的厂房 考试一个小时没调出来,自闭了.......... 正解很好想,最后实在打不出来了只好暴力骗分了... 联想到以前做的题:序列(涉及质因数分 ...