《深入理解C++11》要点总结

3.1 继承构造函数

通过using关键字可以继承父类的构造函数。也可以通过显式定义构造函数来阻止继承。

3.2 委派构造函数,减少构造函数的书写

class Info {
public:
    Info() { InitReset(); }
    Info(int i) : Info() { type = i; }  //通过调用无参构造函数,可以减少构造函数内容的重写
    Info(char e) : Info() { name = e; }  //委派构造函数和初始化列表不能同时存在,使用委派构造函数后,初始化代码需要放在函数体中

private:
    int type { 1 };         //初始化成员变量
    char name { ‘a‘ };

    void InitReset() {}
};

3.3.2 移动语意学

通过移动构造函数可以减少临时对象中的数据拷贝。

3.3.3 左值、右值和右值引用

有名字的可以取地址的是左值(&a),没有名字,不能取地址的是右值( &(b+c)是错误操作 ),所以a是左值,(b+c)是右值

T && a = ReturnRvalue(); //获得一个右值引用,只有在a的生命周期中,函数返回的右值持续存活

右值引用不能绑定左值,如 int c; int && d = c;  //错误

可以通过<type_traits>中的模板类来判断值的类型,如 is_rvalue_reference<string &&>::value;

3.3.4 std::move 将一个左值强制转化为右值引用,从而可以通过右值引用使用该值

如果声明了移动构造函数、移动赋值函数、拷贝赋值函数和析构函数中的一个或多个,编译器不会再生成默认的拷贝构造函数。所以拷贝构造/赋值和移动构造/赋值函数必须同时提供或者都不提供。

3.5 列表初始化

等号加上赋值表达式,如 int a = 3 + 4;

等号加上花括号,如 int a = {3+4};

圆括号式的表达式 ,如 int a (3+4);    可以用于堆内存的new操作,如 int *i = new int(1);

花括号式的表达式,如int a {3+4};     double *d = new double{2.3f};

使用列表初始化,在出现类型收窄时会编译失败,如 char c = {1024}; //无法通过编译

3.8 字面量操作符  ret operator “” _x(arguments) {} 可以定义字面量操作符

struct Watt {
    unsigned int v;
};

Watt operator "" _w(unsigned long long v)
{
    return { (unsigned int)v };
}

如果字面量为整型数,那么字面量操作符函数只可以接受unsinged long long或const char*为参数

如果字面量为浮点型数,函数只可接受long double或const char*为参数

如果字面量为字符串,函数只接受const char*, size_t为参数

如果字面量为字符,函数只可以接受一个char为参数

4.2 auto 自动类型推导

使用auto声明的变量必须被初始化,从而使编译器能够从初始化表达式中推导出其类型

auto可以用于new关键字,auto z = new auto(1);

auto不能用作形参的类型,即使提供了默认参数,如  void fun(auto x = 1) {} //编译失败

auto也不能用于结构体的非静态成员变量,即使成员拥有初始值,如 struct str { auto var = 10; } //编译失败

不能声明auto数组

在实例化模板的时候不能使用auto作为模板参数,如 vecotr<auto> v = {1};  //编译失败

4.3 decltype可以用于获取对象类型,获取的类型可以用于定义对象,如 vector<int> vec; typedef decltype(vec.beging()) vectype;

decltype只接受表达式作为参数(如,decltype( Func(x)),而不接受 decltype( Func ) ),和auto一样在编译时确定类型

4.4 追踪返回类型,使用auto和decltype可以追踪返回类型

template<typename T1, typename T2>
auto Sum(T1 & t1, T2 & t2) -> decltype(t1 + t2) {
    return t1 + t2;
}

auto (*fp)() -> int;  等价于  int (*fp)();

5.1 强类型枚举

enum class Type: char { General, Light, Medium, Heavy };

6.1.2 常量表达式函数 constexpr

函数必须有返回值

函数体只有单一的return返回语句,函数体只有一条语句,且这条语句是return。可以有static_assert

在使用前必须已有定义

return 返回语句表达式中不能使用非常量表达式的函数、全局数据,且必须是一个常量表达式

常量表达式的构造函数约束:函数体必须为空;初始化列表只能由常量表达式来赋值。

6.1.3 常量表达式值

const int i = 1; 与 constexpr int j = 1; 大部分情况下相同,区别是如果 i 在全局名字空间中,编译器一定会为 i 产生数据,而对于 j ,如果不是有代码显示地使用了它的地址,编译器可以选择不为它产生数据,而仅将其当做编译器的值。

6.2.2 变长模板

template <typename… Elements> class tuple;   // Elements为模板参数包

6.3.2 原子操作 atomic

atomic_llong total {0}; //原子数据类型,多线程访问时不需要加锁

std::atomic<T> t; //atomic类模板,可以任意定义出需要的原子类型

原子类型只能从其模板参数类型中进行构造,不允许原子类型进行拷贝构造、移动构造以及使用operator=等。

7.1.2 nullptr

nullptr不能转换为非指针类型,即使使用 reinterpret_cast<nullptr_t>()的方式也不可以

nullptr不适用于算术运算表达式,也不能进行取地址操作

7.2.2 =default 显式的声明函数为缺省函数,=delete 显式的声明函数为删除函数(不可使用和重载)

显示删除也可以避免编译器做一些不必要的隐式数据类型转换,此时不要和explicit共同使用,如 void Func(char c) = delete; 会导致 Func(‘c’);无法通过编译

7.3.2 lambda函数

[capture] (parameters) mutable ->return-types {statement}

lambda和仿函数类似,实际上仿函数是编译器实现lambda的一种方式

对于按值方式传递捕捉列表,传递的值在lambda函数定义的时候就决定了,而按引用方式传递的值则等于lamdba函数调用时的值。

lambda的捕捉列表仅能捕捉父作用域的自动变量,而对超出这个范围的变量是不能被捕捉的。

8.1.1 alignas 可以设定结构体的对齐方式,alignof获取结构体的对齐大小

struct alignas(32) AlignedColorVector {
    double r;
    double g;
    double b;
    double a;
};

8.2.2 通用属性,使用左右双中括号包含

[[ attribute-list ]]

[[ attr1 ]] void fun [[ attr2 ]] ();

[[ attr1 ]] int array [[ attr2 ]] [10];

C++11中的预定义通用属性包括 [[ noreturn ]] 标识不会返回的函数,[[ carries_dependency ]] 标识不会将控制流返回给原调用函数的函数,如

[[ noreturn ]] void ThrowAway() {

throw "exception”;

}

8.3.2 UTF-8 采用的变长存储方式,无法通过数字式访问读取数据,更多的使用序列化时节省存储空间。定长的UTF-16或UTF-32更适合在内存环境中操作。

其他:

在C++11中std的bind1st和bind2st被bind模板所代替

时间: 2024-10-12 13:41:36

《深入理解C++11》要点总结的相关文章

[.NET] 《Effective C#》快速笔记 - C# 高效编程要点补充

<Effective C#>快速笔记 - C# 高效编程要点补充 目录 四十五.尽量减少装箱拆箱 四十六.为应用程序创建专门的异常类 四十七.使用强异常安全保证 四十八.尽量使用安全的代码 四十九.实现与 CLS 兼容的程序集 五十.实现小尺寸.高内聚的程序集 这是这一系列的最后一篇. 四十五.尽量减少装箱拆箱 值类型是数据的容器,不支持多态. 装箱把一个值类型放在一个未确定类型的引用对象中,让该值作为引用类型所使用.拆箱指从引用类型的位置取出值的一个副本. 装箱拆箱都是比较影响性能的手段,应

《Effective C#》快速笔记 - C# 高效编程要点补充

目录 四十五.尽量减少装箱拆箱 四十六.为应用程序创建专门的异常类 四十七.使用强异常安全保证 四十八.尽量使用安全的代码 四十九.实现与 CLS 兼容的程序集 五十.实现小尺寸.高内聚的程序集 这是该系列的最后一篇.也许有些理论有可能会过时,我想它仍有存在的必要,人的知识水平也是一个不断成长的过程,学会站在前人的肩膀上,尝试不断的借鉴与总结. 四十五.尽量减少装箱拆箱 值类型是数据的容器,不支持多态. 装箱把一个值类型放在一个未确定类型的引用对象中,让该值作为引用类型所使用.拆箱指从引用类型的

《More Effective C++》要点总结

1.指针与引用的区别 任何情况下都不能使用指向空值的引用,使用时必须初始化.这使得使用引用时的效率比使用指针要高,因为在使用之前不需要测试它的合法性. 引用总是指向在初始化时指定的对象,以后不能改变. 重载某个操作符时,应该使用引用. 2.尽量使用C++风格的类型转换 static_cast, const_cast, dynamic_cast, 和 reinterpret_cast. (double)number,改成使用static_cast<double>(number). 3.不要对数组

《Effective Java》要点总结

1. 用静态工厂方法代替构造器. 2.遇到多个参数构造器时考虑用构建器. 3.用私有构造器或美剧型强化Singleton. 4.通过私有构造器强化不可实例化的能力. 5.避免创建不必要的对象. 尽量使用String str = "XXX":而不是String str = new String("XXX"): 6.消除过期的对象引用. 7.避免使用终结方法. 终结方法的何时被调用或是否被调用是不确定的. 8.覆盖equals是要遵守通用规定. 需要遵守自反性.对称性.

《Effective Modern C++》要点中英文对照

目录 CHAPTER 1 Deducing Types 章节1 类型推导 Item 1:Understand template type deduction. 条款1:理解模板类型推导. Item 2:Understand auto type deduction. 条款2:理解auto类型推导. Item 3:Understand decltype. 条款3:理解decltype. Item 4:Know how to view deduced types. 条款4:知道如何查看推导出来的类型.

Effective前端1:能使用html/css解决的问题就不要使用JS

  借用Effective之名,开始写Effective系列,总结一些前端的心得. 为什么说能使用html/css解决的问题就不要使用JS呢?两个字,因为简单.简单就意味着更快的开发速度,更小的维护成本,同时往往具有更好的体验,下面介绍几个实例. 1. 导航高亮 导航高亮是一种很常见的问题,包括当前页面的导航在菜单里面高亮和hover时高亮.你可以用js控制,但是用一点CSS技巧就可以达到这个目的,不需要使用JS. 在正常态时,每个导航的默认样式为: 正常态透明度为0.5 CSS 1 2 3 n

Objective-C 2.0 基础要点归纳

本文的阅读基本条件: 具备C/C++基础知识,了解面向对象特征 阅读过<Objective-C 2.0 程序设计(第二版)>.<Objective-C 程序设计 第6版>或相关基础OC书籍 参考资源: 1.<Effective Objective-C2.0> 2. <Objective-C 2.0 程序设计(第二版)>/<Objective-C 程序设计 第6版> 3. http://www.cnblogs.com/pengyingh/artic

Effective Modern C++ 读书笔记 Item 1

最近发现了<Effective Modern C++>这本书,作者正是大名鼎鼎的Scott Meyers——<Effective C++>.<Effective STL>的作者. 而就在C++11逐渐普及,甚至是C++14的新特性也进入大家的视野的时候,<Effective Modern C++>一书应运而生.此书与其前辈一样,通过数十个条款来展开,只不过这次是集中于C++11和C++14的新特性.auto.decltype.move.lambda表达式……

【《Effective C#》提炼总结】提高Unity中C#代码质量的22条准则

本文由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/53869998 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 引言 我们知道,在C++领域,作为进阶阅读材料,必看的书是<Effective C++>. 而<Effective C#>之于C# ,是类似<Effective C++>之于C++一样的存在. 这篇文章,

《Effective C++》重点摘要(八)

<Effective C++>第八章:定制new和delete 了解new-handler的行为.new和delete不是函数,是申请和释放内存的操作符.当new提出获得内存申请失败时会发生什么?老旧的编译器是返回null指针.现在呢,如果申请失败,会先调用一个错误处理函数,那就是new-handler.这就像一个回调函数,系统有一个默认的,用户也可以自行编写一个错误处理函数并使用set_new_handler函数设置之.通常自行编写的错误处理函数可以使用这些策略: 1) 多次尝试申请内存.