| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> 《Modern Effective C++》学习笔记3 转向现代C++ -> 正文阅读 |
|
[C++知识库]《Modern Effective C++》学习笔记3 转向现代C++ |
条款七:在创建对象时注意区分()和{}大括号初始化的出现是为了进行统一初始化,实现一种从概念上可以用于一切场合的初始化,从以下例子中可以窥见: ?class Widget { ? ? ...... ?private: ? ? ?int x{0}; // 可行 ? ? ?int y = 0; // 可行 ? ? ?int z(0); // 不可行 ?} ?? ?// 不可复制对象 ?std::atomic<int> ai1{0}; // 可行 ?std::atomic<int> ai2(0); // 可行 ?std::atomic<int> ai3 = 0; // 不可行 {}的优缺点 优点:
?double x,y,z; ?int sum{ x + y + z }; // 不可行
?// 对于调用没有形参的构造函数容易解析错误 ?Widget w1(); // 会被解析成返回值为Widget,无输入参数的函数声明 ?Widget w2{}; // 由于函数声明不能用{}来指定形参列表,使用{}就没这个问题了 ? ? // 注意语言规定这里会调用默认构造函数,而不调用std::initializer_list<>入参的构造函数 ?Widget w3({}); // 这里会调用std::initializer_list<>入参的构造函数 缺点:
?vector<int> v1(10, 20); // 20个元素,每个元素是10 ?vector<int> v2{10, 20}; // 2个元素,分别是10和20 怎么选择呢? 坚持一种就好,但要了解这些限制和特殊情况。 条款八:优先选用nullptr,而非0或NULL0和NULL都不具备指针型别,而nullptr虽然也不具有指针型别,但可以隐式转换到所有的裸指针型别。 nullptr的优点:
条款九:优先选用别名声明而非typedeftypedef不支持模板化,但别名声明支持,例如下面代码: ?template<typename T> ?using MyAllocList = std::list<T, MyAlloc<T>>; ?? ?MyAllocList<Widget> lw; 而使用typedef就需要写成这样,使用时得加上type后缀,就像C++11中的变换std::transformation<T>::type: ?template<typename T> ?struct MyAllocList { ? typedef std::list<T, MyAlloc<T>> type; ?}; ?? ?MyAllocList<Widget>::type lw; 而且当你想如下使用typedef类型来创建一个目标那中的链表的话,你还必须加上第4行这个typename 关键字 ?template<typename T> ?class Widget { ?private: ? typename MyAllocList<T>::type list; ?} 条款十:优先选用限定作用域的枚举类型,而非不限作用域的枚举类型限定作用域的枚举类型: ?enum class Color { ? black, ? white, ? red ?}; ?? ?Color c = Color::white; 优点:
不限作用域的枚举类型: ?enum color { ? black, ? white, ? red ?}; 优点:
条款十一:优先选用删除函数,而非private未定义函数优点:
?template <> ?void processorPointer<void>(void*) = delete; 注:一般进行删除的时复制构造函数和复制赋值运算符。 条款十二:为意在改写的函数添加override声明C++11中为override增加了一个限制,改写的函数的引用饰词必须完全相同,见下面例子: ?class Widget { ?public: ? ? ?void doWork() &; // 这个版本的doWork仅在*this是左值时使用 ? ? ?void doWork() &&; // 这个版本的doWork仅在*this是右值时使用 ?}; ? ? ? ?Widget makeWidget(); // 工厂函数,返回右值 ?makeWidget().doWork(); // 调用 void doWork() && 版本 ?? ?Widget w; ?w.doWork(); // 调用 void doWork() & 版本 条款十三:优先选用const_iterator,而非iterator可以使用cbegin()和cend()函数返回const_iterator(C++14) 在通用代码中,优先选用非成员函数版本的begin,end和rbegin等函数,它们能对未提供该种成员函数的容器也适用。 条款十四:只要函数不会发射异常,就为其加上noexcept声明为什么呢?
条款十五:只要有可能使用constexpr,就使用它
从以上两点来看,constexpr扩展了语境,而且兼容了已知的情况,推荐使用。 条款十六:保证const成员函数的线程安全性std::atomic比mutex具有更好的性能,但是只适用于单个变量或内存区域的情形,多个时mutex才是合适的选择。 条款十七:理解特种成员函数的生成机制什么是特种成员函数? 就是那些只有在需要时才生成的默认函数,目前有如下几种:
为什么我们要了解这些函数的生成机制? 假设我们显式定义了一个析构函数,这个操作会阻止默认移动操作的生成,但是我们代码中的移动操作并不会报错,而会执行复制操作,极大的降低了性能。 那么这机制到底是什么样呢?
另外,存在一个例外,那就是成员模板函数,成员模板函数在什么时候都不会阻止生成任何特种成员函数。例如如下代码并没有影响。 ?class Widget { ? template<typename T> ? ? ?Widget(const T& rhs); // 模板复制构造函数 ? ? ? ? ? ?template<typename T> ? ? ?Widget& operator=(const T& rhs); // 模板复制赋值运算符 ?}; |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 0:49:50- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |