深入理解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内存模型规定,所有的变量都必须存储在主内 ...
随机推荐
- 使用 “恢复模式” 或 “DFU 模式” 来更新和恢复 iOS 固件
请访问原文链接:https://sysin.org/article/apple-ios-dfu/,查看最新版.原创作品,转载请保留出处. 作者:gc(at)sysin.org,主页:www.sysin ...
- 解决使用go get 下载模块下载超时的问题
解决使用go get 下载模块下载超时的问题 解决使用go get 下载模块下载超时的问题 使用go env可以看到,默认的GOPROXY的值是https://proxy.golang.org, ...
- Linux分区创建、挂载
fdisk -l 这块盘是没有分区的,没有被使用. fdisk /dev/vdb 操作这块磁盘, 创建分区 格式化/dev/sdb1为ext4 mkfs -t ext4 /dev/vdb1 mkfs. ...
- 目标检测中特征融合技术(YOLO v4)(上)
目标检测中特征融合技术(YOLO v4)(上) 论文链接:https://arxiv.org/abs/1612.03144 Feature Pyramid Networks for Object De ...
- cuSPARSELt开发NVIDIA Ampere结构化稀疏性
cuSPARSELt开发NVIDIA Ampere结构化稀疏性 深度神经网络在各种领域(例如计算机视觉,语音识别和自然语言处理)中均具有出色的性能.处理这些神经网络所需的计算能力正在迅速提高,因此有效 ...
- TVM Reduction降低算力
TVM Reduction降低算力 这是有关如何降低算力TVM的介绍材料.像sum / max / min这样的关联约简运算符是线性代数运算的典型构造块. 本文将演示如何降低TVM算力. from _ ...
- 深度学习框架集成平台C++ Guide指南
深度学习框架集成平台C++ Guide指南 这个指南详细地介绍了神经网络C++的API,并介绍了许多不同的方法来处理模型. 提示 所有框架运行时接口都是相同的,因此本指南适用于所有受支持框架(包括Te ...
- 图像超分辨率算法:CVPR2020
图像超分辨率算法:CVPR2020 Unpaired Image Super-Resolution using Pseudo-Supervision 论文地址: http://openaccess.t ...
- Vue packages version mismatch的解决方法 初来乍到,踩坑日常
初来乍到,踩坑日常 这个问题也是我也是接受别人项目,出现的问题,在下载好依赖后运行的时候报这样的错误 它上面显示两个版本一个vue的版本,一个vue-template-compiler版本,我这边忘了 ...
- 【题解】P2854 [USACO06DEC]牛的过山车Cow Roller Coaster
P2854 [USACO06DEC]牛的过山车Cow Roller Coaster 题目描述 The cows are building a roller coaster! They want you ...