effective modern C++读书笔记

类型推导:

1.ParamType是reference或pointer,不是universal reference

有引用则忽略引用,其余部分匹配T

template <typenmae T>
void f(T& param);

int x = 27;
const int cx  =x;
oonst int& rx = x;

f(x);//T is int, paramtype is int&
f(cx);//T is const int, paramtype is coint int&
f(rx);//T is const int, paramtype is coint int&

2.paramType是universal reference

1)如果是lvalue,T被推导为引用,paramType也是引用

2)如果是rvalue,使用1的规则

template<typename T>
void f(T&& param);
int x = 27;
const int cx = x;
const int & rx = x;

f(x);//x is lvalue, T is int&, paramtype is int&
f(cx);//x is lvalue, T is const int&, paramtype is const int&
f(rx);//x is lvalue, T is const int&, paramtype is const int&
f(27);//27 is rvalue, T is int, paramType is int&&

3.非引用,非指针

expr中有reference,忽略掉;有const,忽略掉;有volatile,忽略掉。

template<typename T>
<pre name="code" class="cpp">void f(T param);
int x = 27;
const int cx = x;
const int & rx = x;
//以下全部T paramtype都为 int
f(x);

f(cx);

f(rx);


auto的推导规则与template基本相同,除了以下:

auto于初始化braced initializer时初始化为std::initializer_list,而template type deduction不会

auto x = {1,2,3}; //类型是std::initializer_list<int>

tips:

auto作为函数返回或lambar参数时时template type deduction的方式。

此外,使用auto的情况,尤其是初始化对象的时候必须是类型明确的时候。

modern C++:

7.区分创建对象时的(),{}

e.g:

std::vector a(3,0);  //创建3个0的vector
std::vector b{1,2,3};//创建1,2,3的vector

8-15:使用新标准的关键字

nullpter代替0,

使用using代替typedef,

使用delete删除不必要的函数,

使用override表明函数覆盖,

使用const_iteratorter替代iterator,

使用noexcept在函数无异常时,

使用constexpr对编译器就能编译的函数

16.使函数具有线程安全性

C++11具有新的内存模型,支持多线程编程

17.理解编译器生成的函数

6种函数:default constructor,destructor,copy operations(copy constructor,copy assigment),move operations

move operation只在类缺少move operation,copy operation and destructor时生成

copy constructor只在缺少明确的copy constructor时生成,在move operation声明时删除。

copy assignment opetaor只在只在缺少明确的copy assignment opetaor时生成,在move operation声明时删除。

函数模板不能阻止特殊函数生成

智能指针:

独占资源使用std::unique_ptr,共享资源使用std::shared_ptr,配合std::shared_ptr使用std::weak_ptr;

使用std::make_unique,std::make_shared代替创建对象(不违反成对出现new,delete的原则),另外传给这两个函数的是作为被创建对象的参数。

小心循环引用。

auto_ptr复制的时候是浅复制,指向底部的区域是同一块。

右值语义,移动语义,perfect forwarding:

std::move将对象转换为rvalue;std::forward转换为rvalue仅当参数绑定为右值,其他情况都为左值;std::move,std::forward都是编译器转换

universal reference指对象满足类型推导和&&时;universal reference转为rvalue只有参数为rvalue时,否则全为lvalue;

std::move配合rvalue使用,std::forward配合universal
reference使用;

universal
reference使用时避免重载,

e.g:

templte<typename T>
void logandadd(T&& name){...};

void logandadd(int idx){...};

logandadd(22);   //cals int overload

short nameidx;
logandadd(nameidx);  //error

以及解决这种情况的方案:在pass by lvalue-reference-to-constant, pass by value, tag dispatch,
放弃重载之间抉择

reference
collapsing:编译器生成a reference ti a
reference,结果变为一个单独的reference;只有两个都是rvalue reference才会得到rvalue reference,否则都是lvalue
reference

编译器生成后产生的情况:

template<typename T>
void func(T&& param);

Widget widget();
Widget w;

func(w);//call func with lvalue;
func(widget());//call func with rvalue

熟悉std::forward失败场景,如braced initializers,0或NULL或null pointers,重载函数和模板函数,bitfield

lambda表达式:

避免默认捕获,针对每个捕获参数设置&或者=;

&捕获时,外部被捕获的对象值在生命期必须大于该闭包。否则,会出现闭包调用时,该对象已经析构;

使用init capture移动参数进入闭包

auto func = [pw = std::make_unique<Widget>()]{...};

配合auto&&和std::forward使用(C++14)

C++多线程:

选择task-based比thread-based好。任务通常独立,降低了线程与线程间的关联,减少了线程同步的使用,自然更容易使用

std::launch::async关键字使用但异步必要的时候,launch的介绍

std::thread在所有路径上都unjoinable,对线程要么join,要么detach

使用std::future替代条件变量,(高级同步原语替代基本同步原语)

使用std::atomic,volatile修饰多线程共享变量(后者让编译器不优化,atomic的介绍

杂项:

类添加对象进入私有容器时,对lvalue和rvalue参数的处理:

1.使用重载函数,一个使用lvalue参数,一个使用rvalue参数

2.使用universal reference

3.传值

三种方案的消耗:

1.一次复制对lvalue,一次移动对rvalue

2.如上

3.在函数体重,值参数被move进容器,因此比上面两种多一次move,无论lvalue还是rvalue

使用emplacement系列函数代替插入

1.减少了途中的操作,更高效

vector的emplace

vectoe的emplace_back

时间: 2024-08-02 09:38:19

effective modern C++读书笔记的相关文章

[C++11] Effective Modern C++ 读书笔记

本文记录了我读Effective Modern C++时自己的一些理解和心得. item1:模板类型推导 1)reference属性不能通过传值参数传入模板函数.这就意味着如果模板函数需要一个reference类型的参数,必须在模板声明中将其声明为reference,否则,即使使用一个reference类型的变量调用模板函数,类型推导的结果将不带reference属性. 2)constant和volatile属性也不能通过传值参数传入模板函数,但是可以通过reference参数传入这些属性. 3

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表达式……

[.NET] 《Effective C#》读书笔记(二)- .NET 资源托管

<Effective C#>读书笔记(二)- .NET 资源托管 简介 续 <Effective C#>读书笔记(一)- C# 语言习惯. .NET 中,GC 会帮助我们管理内存,我们并不需要去担心内存泄漏,资源分配和指针初始化等问题.不过,它也并非万能,因为非托管资源需要我们自己进行清理,如文件句柄.数据库连接.GDI+ 对象和COM 对象等. 目录 十二.推荐使用成员初始化器而不是赋值语句 十三.正确地初始化静态成员变量 十四.尽量减少重复的初始化逻辑 十五.使用 using

《Effective C++》 读书笔记之三 资源管理

<Effective C++> 读书笔记之三 资源管理 准备知识: 所谓资源就是,一旦用了它,将来必须还给系统.最常用的资源是动态分配内存,其他常见的资源有文件描述器.互斥锁.图形界面的字形和笔刷.数据库连接以及网络sockets. auto_ptr 是个"类指针对象",就是所谓的智能指针,其析构函数自动对其所指对象调用delete.auto_ptr位于 #include <memory> 头文件.由于auto_ptr被销毁时会自动删除它所指之物,所以一定要注意

《Effective C++》 读书笔记之四 设计与申明

<Effective C++> 读书笔记之四 设计与申明 条款18:让接口容易被正确使用,不易被误用. 重点: 好的接口很容易被正确使用,不容易被误用.你应该在你的所有接口中努力达成这些性质. "促进正确使用"的办法包括接口的一致性,以及与内置类型的行为兼容. "阻止误用"的办法包括建立新类型.限制类型上的操作,束缚对象值,以及消除客户的资源管理责任. tr1::shared_ptr支持定制型删除器.这可防范DLL问题,可被用来自动解除互斥锁等等. 20

《Effective C++》读书笔记汇总

我之前边读<Effective C++>边写下每个条款的读书笔记,这一版是C++11之前的版本.这里我将每个条款令我印象深刻的点小结一下. 1.C++包括:Plain C(面向过程).OOP(面向对象).模板(泛型和模板元编程).STL(C++标准库). 2.用inline.enum.const代替#define.#define定义的宏,一旦复杂起来,高手都很难掌控.不要带入C的习惯. 3.灵活使用const前缀.不需要进行改变的数据加上const前缀.指针的const前缀有两种形式,cons

《Effective java》—–读书笔记

2015年进步很小,看的书也不是很多,感觉自己都要废了,2016是沉淀的一年,在这一年中要不断学习.看书,努力提升自己!预计在2016年要看12本书,主要涉及java基础.Spring研究.java并发.JVM.分布式之类的.在今年面试的时候深受打击,到处都是问分布式.集群的?难道现在工作两三年的都这么牛逼了?都在搞分布式.集群之类的? 2016书单如下: 1.深入理解Java虚拟机:JVM高级特性与最佳实践-(已看,预计今年看三遍) 2.Oracle查询优化改写技巧与案例-(已看) 3.Eff

〈Effective C++〉读书笔记--Accustoming Youself to C++

1.View C++ as a federation of languages.把C++看成4种子语言组成,即C.Object-Oriented C++.Template C++.The STL. 2.Things to Remember:Rules for effective C++ programming vary, depending on the part of C++ you are using. 因为C++有很多的编程范式,在项目开发过程中,明确规范怎么使用C++很重要,这样可以使整

〈Effective C++〉读书笔记--Introduction

Introduction 1.Learning the fundamentals of a programming language is one thing; learning how to design and implement effective programs in that language is something else entirely. 想起<重构>里面说的一句话,写出计算机能理解的代码很容易,但是写好人能理解的代码不容易 2.A declaration tells c