
Effective C++读书笔记
IT_iverson
欢迎大家一起交流学习,点击一篇博客进入分类中方便自己阅读!
展开
-
条款30:透彻了解inlining的里里外外
总结心得:1.首先inline只是对编译器的一个申请,不是强制命令,编译器不是要强制执行你的这个inline,他根据实际情况接受或者拒绝。这个申请可以是隐式申请:比如定义在类内部的函数,或者定义在类内部的友元函数,会隐式申请为inline函数 显示申请:在函数前面加inline2.inline一般情况下放在头文件中,因为编译器在编原创 2017-11-07 23:19:19 · 258 阅读 · 0 评论 -
条款17:以独立的语句将newed对象置入智能指针
本条款的核心思想只有一句话:那就是在使用智能指针管理对象的时候,一定用一条单独的语句将new出来的对象放入智能指针当中去。下面举个例子说明一下:假设有如下的代码:class Widget {....}; int priority();//函数1 void processWidget(std::trl::shared_ptr pw, int size);//函数2 //调用函数原创 2017-11-30 14:52:57 · 351 阅读 · 0 评论 -
条款08:别让异常逃离析构函数
总结:1.在析构函数中尽量不要有抛出异常的事情发生,如果析构函数中抛出了异常,析构函数应该自己捕捉这个异常,然后根据程序需要终止程序或者吞下这个异常然继续执行程序 2.如果需要客户对于某个操作的函数运行期间所抛出的异常做出反应,这个时候应该将这个抛出异常的 函数单独写在一个函数中,而不是在析构函数中执行。打眼一看这两句话有点迷不知道几个意思,其实这个条款的核心内容就是告诉你尽量不要让原创 2017-11-16 16:35:55 · 337 阅读 · 0 评论 -
条款20:宁以pass-by-reference-to-const替换pass-by-value
首先解释一下这个标题的意思吧,就是使用引用传参来替换传值传参,因为传值传参相比传引用来说有着太多的不方便,下面我来详细说明一下理由1.理由1.使用by value会产生很多麻烦的过程(比如调用拷贝构造函数等一系列不必要的函数),看如下代码int n = 0;class String{public: String() { n++; cout << "String::构造函数原创 2017-12-01 18:53:29 · 284 阅读 · 0 评论 -
必须返回对象时,别妄想返回其reference
此条款核心的宗旨就是在需要返回一个对象的时候不要试图返回他的引用。尽管你可能会在成本之间纠结,但是最终的正确才是你要的结果。下面用operator*来举例子说名这个问题。因为大家都直到oerator返回的是对象绝不是引用1.有如下代码class Rational{private: int a, b;public: friend const Rational operato原创 2017-12-02 21:05:12 · 595 阅读 · 0 评论 -
条款13-15(资源管理,其实就是讲的智能指针)
对于智能指针我博客中C++部分有关于它的介绍,不知道的可以去看看。下面我来总结一下原创 2017-11-23 17:38:05 · 381 阅读 · 0 评论 -
条款22:将成员变量声明为private
本条款的核心内容就是告诉你,为什么要把成员变量声明为private,并且让你服服帖帖的认同这个观点!理由1:从语法一致性来讲如果成员变量不是public的话,客户访问成员变量的唯一途径就是通过public的成员函数,如果public内的每个东西都是函数的话,客户在访问class成员的时候只需要记住后面加()就可以了,不需要记住其他的一些东西,因为你访问的都是函数,这是不是很方便原创 2017-12-04 14:38:23 · 322 阅读 · 0 评论 -
条款16:成对使用new和delete的时候要采取相同形式
本条款将的核心内容就是new和delete搭配,new []和delete[]搭配。不要混合乱用。下面我们来解释为什么1.首先来看new和delete记住:new/delete是C++中的关键字不是函数,下面我们来看看他们背后的机制为什么比malloc使用起来简单了很多呢。(下面的例子用自定义类型说明,自定义类型最后在说)首先来说new,看如下代码class test{原创 2017-11-24 19:38:50 · 468 阅读 · 0 评论 -
条款23:宁以non-memeber,non-friend替换member函数
本条款的核心就是告诉我们用非成员函数和非友元函数比用成员函数好!主要是从封装的角度出发才有这个结论的!下面来看理论阐述和解释1.首先看如下的代码class WebBrowser{public: void claercache(); void clearhistory(); void removecookies();};加入上面的这个类中的函数要一次性执行上面三个函数,我们可以用原创 2017-12-05 16:48:30 · 241 阅读 · 0 评论 -
条款24:若所有参数需要类型转换,请为此采用no-member函数
本条款的核心内容是:如果一个函数的所有参数(包括this指针所指的那个隐喻的参数)需要进行类型转换的时候,那么这个函数必须是非成员函数。当然这句话只是内含真理,并不是说就是真理,因为在加入模版编程的时候,就会又有一些新争议,新解法,以及令人惊讶的一些设计。这些将形成了条款46下面我来详细介绍本条款:原创 2018-01-19 13:28:53 · 515 阅读 · 0 评论 -
条款09:绝不在构造和析构过程中调用virtual函数
此篇文章主要就是围绕标题来阐述的,没有过多的其他的知识点的总结。总结:1.尽量不要在构造函数和析构函数中调用虚函数(注意这只是个建议,并不是说这样调用编译器一定会报错),因为这样的调用得不到你想要的结果。为什么呢?下面看我来一步步分析首先我们看下面这个代码class Base{public: Base() { cout << "Base::构造函数" << end原创 2017-11-15 17:10:31 · 381 阅读 · 0 评论 -
条款12:复制对象时勿忘其每个成份
此篇文章的核心内容其实也很简单,就是题目所讲的那样,在写拷贝构造函数和赋值运算符重载函数的时候别忘了拷贝你类中的任何一个成份,尤其是派生类更需要注意这点。下面我简单总结一下文章的内容吧。1.为什么会提这个条款呢?因为设计良好的面向对象系统的就是将对象的内部封装起来,只留两个函数负责对象的拷贝(复制),这两个函数就是拷贝构造函数和赋值运算符重载函数,所以有必要提一下关于这两个函数应该注意的一原创 2017-11-20 15:58:02 · 333 阅读 · 0 评论 -
条款07:为多态基类声明virtual析构函数
总结:1.带有多态性质的基类,应该将其析构函数声明为virtual,如果class带有任何虚函数,他就应该有一个virtual的析构函数。因为如果一个基类的指针指向派生类的对象,而这个基类的析构函数不是虚函数的话,那么在销毁这个指针的时候,派生类对对象中的派生类成份没有被销毁,这样会造成诡异的局部销毁,从而形成资源泄露。首先来看代码如下:class Base{public: Ba原创 2017-11-14 18:19:45 · 1204 阅读 · 0 评论 -
条款32:确定你的public继承塑模出is-a关系
.首先看见标题是不是有点懵,感觉很高大尚唬人的一个名字is-a,但是下面我就来解释一下什么是is-a关系,看完本篇博客后你就觉得其实原来是个“挫逼”!1.public继承意味着is-a的关系,简单来讲is-a的关系就是:适用于基类的每一件事情一定也适用于public继承的派生类身上,因为每个派生类也都是一个基类对象。在基类可以派上用场的任何地方,派生类一样可以派上用场,因为每个派生类对象都原创 2017-11-08 10:52:18 · 331 阅读 · 0 评论 -
条款33:避免遮掩继承而来的名称
注意:此篇文章主要讲的是作用域的问题,重点不是继承。首先说一下重载,重写(覆盖),重定义(隐藏)的概念区别:1.重载:①在相同的作用域中②函数名字相同,参数列表不同,不能靠返回类型来判断是否重载2.重写(覆盖):位于基类和派生类①被重写的函数不能是static,必须是virtual。②重写的函数必须有相同的类型,参数列表,函数名。3.重定义(隐藏):位于基类和派生类①如果函数不是一原创 2017-11-08 15:44:19 · 296 阅读 · 0 评论 -
条款02:尽量以const,enum,inline替换#define
1.用const替换#define(宁可编译器替换预处理器)理由:假设#define sign 1.653,当你使用这个宏定义的时候,在预处理期间在你使用sign的地方就被替换为1.653,sign有可能没有进入记号表中,这个时候当此处发生错误,错误可能提示的是发生在1.653,当程序很大时或者sign被定义在其他文件时,你会对于1.653很迷惑不知道来自何处,于是将追踪它而浪费时间,所以用c原创 2017-11-09 10:55:34 · 299 阅读 · 0 评论 -
条款03:尽可能的使用const
首先大概说一下const可修饰的:const用在class的外部可以修饰global或者namespace作用域中的常量,或者修饰文件,函数,或者区块作用域中被声明为static的对象。当然也可以修饰class内部的static和no-static成员变量,也可以修饰指针变量自身或者指针所指物。1.const修饰指针int a = 10;const int* p = &a;//指针所指空原创 2017-11-09 15:14:49 · 283 阅读 · 0 评论 -
条款04:确定对象被使用前已经先被初始化
总结如下:1.访问为初始化的值会导致不明确的行为,有时仅仅因为读取为初始化的值,就可能让你的 程序崩溃,或者读入一些随机值污染整个程序。2.对于内置类型的初始化需要自己去手动完成,除此之外的任何东西,初始化的责任在落在构造函数身上,记住:确保每一个构造函数都能将对象的每一个成员初始化3.对于成员变量的初始化有两种方法 ① .在构造函数内赋值:class Test原创 2017-11-11 16:31:51 · 391 阅读 · 0 评论 -
条款05:了解C++默默编写并调用哪些函数
总结:1.当你编写的空类被C++编译处理过后,如果你没有声明,则编译器会为空类声明:①默认构造函数②默认拷贝构造函数③赋值运算符重载函数④默认析构函数,这些函数都是public而且是inline,且默认的析构函数是非virtual的注意:唯有当这些函数需要被调用的时候,他们才会被编译器创建出来。注意:对于如果你不写默认构造函数,编译器就会为你生成默认构造函数这种说法是错误的!上面也说了唯有原创 2017-11-12 18:01:16 · 372 阅读 · 0 评论 -
条款10:令operator=返回一个reference to *this
总结:1.这个条款的主要内容就是想告诉你在赋值运算符重载的时候返回一个指向对象的引用(reference to *this),但是注意这知识个协议,意味着大家都去遵守这个协议,并不是说一定要你写成返回对象的引用。为什么要写成成返回对象的引用呢?下面我来解释一下。一般情况的赋值我们可以写出如下形式int x, y, z;形式1:x = y;形式2:x = y = z;形式3:x原创 2017-11-17 15:25:34 · 317 阅读 · 0 评论 -
条款11:在operator=中处理“自我赋值”
总结:1.此篇条款主要讲了在自我赋值中可能发存在的一些安全隐患,和推荐了一些解决这些问题的好的operator=的实现方法。自我赋值如果是程序员自己可能觉得这种弱智的问题怎么会发生在自己身上呢?但是客户可不管你这些,所以首先列举一些不经意间就自我赋值的一些情况。①最明显的不过于x=x这种自我赋值。②arr[i]=arr[j],如果i=j这就是一个潜在的自我赋值③对于不同的指针或原创 2017-11-17 17:23:21 · 337 阅读 · 0 评论 -
条款06:若不想编译器自动生成的函数,就该明确拒绝
总结如下:1.想要防止对象的拷贝,你可以将拷贝构造函数和赋值运算符重载函数声明为private,而且不实现他们,这样在对象试图拷贝的时候就会报出链接错误。class A{public: A(int x) :_a(x){}private: int _a; A(const A&);//声明私有拷贝构造函数 A& operator=(const A&);//声明私有赋值运算符重载原创 2017-11-13 14:50:11 · 352 阅读 · 0 评论 -
条款25:考虑写出一个不抛出异常的swap函数
首先本篇博客的主要思想是:系统自带的swap函数有时候不能满足我们的需求,所以在一些情况下我们就需要自己去写swap函数。此条款的主要内容就是告诉你该如何去写你要的swap函数,下面开始正文来好好地介绍一下此条款的内容1.首先来看一下库里面给的swap函数的原型可以看出来标准程序库提供的swap函数是这样的实现的,通过拷贝和赋值来实现。可以看出来他也没有提供异常安全,所以在我们自己原创 2018-01-20 15:34:04 · 290 阅读 · 0 评论