![](https://img-blog.csdnimg.cn/20201014180756757.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C++学习笔记
Allen Chou
这个作者很懒,什么都没留下…
展开
-
Effective C++ 读书笔记 Item55 熟悉一下Boost
Boost是一个C++开发者的社区,作为C++标准的试验场, 收容了很多高质量、开源的、跨平台、独立于编译器的C++库, 包括许多TR1组件的实现。Boost是其他C++组织和社区所不能比拟的:与C++标准委员会的亲近关系。Boost社区成员和C++标准委员会成员有很大的交集。 多数C++下一代标准都来自于Boost社区。特殊的项目接收流程。首先在邮件列表中提出它,然后开启整个流程: ...原创 2020-06-21 20:55:26 · 168 阅读 · 0 评论 -
Effective C++ 读书笔记 Item25 考虑实现一个不抛异常的swap
我们可以调用std下的swap函数,这是一个模板函数:既可以: int a = 1; int b = 2; std::swap(a,b); cout<<"a = "<<a<<" b = "<<b<<endl;也可以(前提这个类型支持复制构造函数和赋值构造函数):class Test{pub...原创 2019-08-22 12:58:08 · 110 阅读 · 0 评论 -
Effective C++ 读书笔记 Item10 赋值操作符要返回*this的引用
C++的赋值操作符(assignment operator)有一个有趣的用法:int x, y, z;x = y = z = 15; //链式赋值 (Chained assignment)以上代码会被编译器从最右边开始解析 (right-associative):x = (y = (z = 15)));15先被赋值到z,z又被赋值到y,最后y被赋值到x...原创 2019-08-17 11:53:00 · 149 阅读 · 0 评论 -
Effective C++ 读书笔记 Item9 绝不在构造和析构过程中调用 virtual 函数
假如你在为某证券公司设计股市交易软件,需要有一个类用来表示股市交易:class Transaction{ //股市交易的基类 public: Transaction(); virtual void logTransaction() const =0; //该函数用来记录交易历史,是一个纯虚函数 .....原创 2019-08-17 10:02:11 · 111 阅读 · 0 评论 -
Effective C++ 读书笔记 Item8 析构函数不能抛出异常
构造函数可以抛出异常。C++标准指明析构函数不能、也不应该抛出异常。在步入正题前,我们先来讲讲什么叫栈展开(stack unwinding),才能更好理解C++异常(exception)的机制是怎样运作的:void f1() throw(int){ //函数f1会抛出一个整型的异常代码 cout<<"f1 starts"<<endl;...原创 2019-08-16 23:19:07 · 138 阅读 · 0 评论 -
Effective C++ 读书笔记 Item7 为多态基类声明 virtual 析构函数
析构函数(destructor)用来释放对象所占用的资源。当对象的使用周期结束后,例如当某对象的范围(scope)结束时,或者是动态分配的对象被delete关键字解除资源时,对象的析构函数会被自动调用,对象所占用的资源就会被释放。以及像第五章讲过的,假如在你的类中不声明析构函数,编译器也会为你自动生成一个。多态(polymorphism)则是C++面向对象的基本思想之一,即抽象(abstrac...原创 2019-08-16 21:31:33 · 131 阅读 · 0 评论 -
Effective C++ 读书笔记 Item6 若不想使用编译器自动生成的函数,就该明确拒绝
试想如下情形,某个房地产商所拥有的房子都是不同的,同时你在为这个公司设计程序,而你不想将一座房子的信息拷贝给另一座房子,这就需要禁止使用拷贝构造函数(copy constructor)和拷贝赋值运算符(copy assignment operator)。class House{...};House h1;House h2;House h3(h2); //禁止执行h1=...原创 2019-08-16 18:00:13 · 122 阅读 · 0 评论 -
Effective C++ 读书笔记 Item5 了解 C++默默编写并调用哪些函数
在C++中,编译器会自动生成一些你没有显式定义的函数,它们包括:构造函数、析构函数、复制构造函数、=运算符。 有时为了符合既有设计,我们不希望自动生成这些函数,我们可以把它们显式声明为private。 此时在使用这些类的客户看来,它们就像不存在一样。class Empty{public: // 默认构造函数 Empty(){} // 拷贝构造函数 Em...原创 2019-08-16 17:40:06 · 133 阅读 · 0 评论 -
Effective C++ 读书笔记 Item43 访问模板基类中的名称
从面向对象C++转移到模板C++时,你会发现类继承在某些场合不在好使了。 比如父类模板中的名称对子类模板不是直接可见的,需要通过this->前缀、using或显式地特化模板父类来访问父类中的名称。因为父类模板在实例化之前其中的名称是否存在确实是不确定的,而C++偏向于早期发现问题(early diagnose),所以它会假设自己对父类完全无知。编译错的一个例子一个MsgSen...原创 2019-08-25 23:40:57 · 192 阅读 · 0 评论 -
Effective C++ 读书笔记 Item42 typename的两种用法
时至今日还有人在论坛里问模板参数前的typename和class有何区别:template<typename T> class Widget;template<class T> class Widget;答案是没有区别!有人觉得class写起来方便就用class,有人觉得typename语义更正确就用typename。 然而typename和class对编译器而...原创 2019-08-25 19:13:02 · 205 阅读 · 1 评论 -
Effective C++ 读书笔记 Item41 了解隐式接口和编译器多态
面向对象设计中的类(class)考虑的是显式接口(explicit interface)和运行时多态, 而模板编程中的模板(template)考虑的是隐式接口(implicit interface)和编译期多态。对类而言,显式接口是由函数签名表征的,运行时多态由虚函数实现; 对模板而言,隐式接口是由表达式的合法性表征的,编译期多态由模板初始化和函数重载的解析实现。显式接口和运行时多态一...原创 2019-08-25 16:41:59 · 157 阅读 · 0 评论 -
Effective C++ 读书笔记 Item1-Item4
目录守则01:把C++看做一个语言的集合,而不是单一的语言守则02:尽量使用const, enum, inline, 减少宏变量#define的使用守则03: 尽可能使用const关键字守则04: 在使用前保证对象是初始化的看完C++ Primer,最近吃了安利开始啃Scott Meyers的Effective C++第三版,书中干货不少,非常值得深思借鉴。但是也有点太多了(→...原创 2019-08-16 13:38:15 · 251 阅读 · 0 评论 -
Effective C++ 读书笔记 Item24 若所有参数皆需类型转换,请为此采用(non-member )非成员函数
虽然Item 15:资源管理类需要提供对原始资源的访问中提到,最好不要提供隐式的类型转化。 但这条规则也存在特例,比如当我们需要创建数字类型的类时。正如double和int能够自由地隐式转换一样, 我们的数字类型也希望能够做到这样方便的接口。 当然这一节讨论的问题不是是否应当提供隐式转换,而是如果运算符的所有“元”都需要隐式转换时,请重载该运算符为友元函数。通过运算符重载来扩展用户定义类型时,...原创 2019-08-20 23:26:38 · 157 阅读 · 0 评论 -
Effective C++ 读书笔记 Item23 非成员非友元函数好于成员函数
其实简单来说成员函数是在类中定义的函数,而非成员函数就是普通函数,就是不是在类中定义的函数,其中非成员函数比较典型的是友元函数。下面贴上一些其他的一些区别和理解:成员函数是类定义的一部分,通过特定的对象来调用。成员函数可以隐式访问调用对象的成员,而无须使用成员操作符。友元函数不是类的组成部分,因此被称为直接函数调用。友元函数不能隐式访问类成员,而必须将成员操作符用于作为参数传递的对象。...原创 2019-08-20 23:01:09 · 166 阅读 · 0 评论 -
Effective C++ 读书笔记 Item40 明智而审慎地使用多重继承
使用多继承时, 一个问题是不同基类可能具有相同名称,产生歧义(即使一个名字可访问,另一个不可访问)多继承(Multiple Inheritance,MI)是C++特有的概念,在是否应使用多继承的问题上始终争论不断。一派认为单继承(Single Inheritance,SI)是好的,所以多继承更好; 另一派认为多继承带来的麻烦更多,应该避免多继承。本文的目的便是了解这两派的视角。具体从如下三个方面...原创 2019-08-24 23:37:01 · 161 阅读 · 0 评论 -
Effective C++ 读书笔记 Item11 赋值运算符的自赋值问题
如果我们选择重载一个类的赋值运算符,要注意在自赋值时仍然能够正确工作。自赋值看起来像是不正确的调用方式, 但是在C++中这是合法的而且常常是不可识别的。例如:a[i] = a[j];*p1 = *p2;base = derived之所以会出现自赋值的问题,是因为C++允许变量有别名(指针和引用),这使得一个数据可以有多个引用。首先给一个错误的赋值运算符重载:Widget...原创 2019-08-17 14:20:19 · 134 阅读 · 0 评论 -
Effective C++ 读书笔记 Item12 完整地拷贝对象(拷贝构造函数、复制运算符)
C++有两种拷贝函数(copying function):拷贝构造函数(copy constructor)和拷贝赋值操作符(copy assignment operator)。在第五章我们讲到过,如果在自己定义的类中不声明这些拷贝函数,编译器会自动为你生成。如果我们声明了自己的拷贝函数,程序将会执行我们自己的拷贝函数。我们来看一个栗子:void logCall(const std::str...原创 2019-08-17 22:55:09 · 261 阅读 · 0 评论 -
Effective C++ 读书笔记 Item13 使用对象(智能指针)来管理资源
我们在学习编程时,经常能听到"资源"这个词。资源可能是一个很宽泛的概念,但总体来讲,资源是我们可以用来使用,并且使用完之后要返还给系统的东西。在C++中,资源多数是指动态分配的内存。如果你只用new来分配内存却不在使用完后delete掉,将会导致内存泄漏。其他资源比如文件描述符(file descriptor),Mutex锁,GUI中的字体(font)和画刷(brush),网络接口(socke...原创 2019-08-17 23:02:26 · 136 阅读 · 0 评论 -
Effective C++ 读书笔记 Item54 熟悉一下标准库,比如TR1
C++这个名字是在1983年由Rick Mascitti提出的,C++的曾用名还有”new C”, “C with Classes”。 1998年ISO/IEC 14882发布了第一个C++标准,就是我们常讲的C++98。后续的标准还包括C++03,C++TR1,C++11,C++14。 值得一提的是C++11标准,它已经被主流编译器支持。包含了核心语言的新机能,而且扩展C++标准程序库,并入了大...原创 2019-08-27 22:07:48 · 217 阅读 · 0 评论 -
Effective C++ 读书笔记 Item53 注意编译警告
许多程序员习惯性地忽略编译器警告。他们认为,毕竟,如果问题很严重,编译器应该给一个错误信息而非警告信息,不是吗?这种想法对其他语言或许相对无害,但在 C++,我敢打赌编译器作者对于将会发生的事情比你有更好的领悟。编译警告在C++中很重要,因为它可能是个错误啊! 不要随便忽略那些警告,因为编译器的作者比你更清楚那些代码在干什么。 所以,请严肃对待所有warning,要追求最高warning级别的...原创 2019-08-27 21:42:51 · 225 阅读 · 0 评论 -
Effective C++ 读书笔记 Item52 写了placement new就要写placement delete
placement new 是带有额外参数的 operator new,但是通常都指“接受一个指针指向对象该被构造之处”的operator new。这个版本被纳入了 C++标准程序库。“placement new”通常是专指指定了位置的new(std::size_t size, void *mem),用于vector申请capacity剩余的可用内存。 但广义的”placement new”指...原创 2019-08-27 21:09:36 · 187 阅读 · 0 评论 -
Effective C++ 读书笔记 Item51 new和delete时请遵循惯例
Item 50介绍了如何自定义new和delete但没有解释你必须遵循的惯例, 这些惯例中有些并不直观,所以你需要记住它们!operator new需要无限循环地获取资源,如果没能获取则调用”new handler”,不存在”new handler”时应该抛出异常; operator new应该处理size == 0的情况; operator delete应该兼容空指针; operato...原创 2019-08-27 20:15:35 · 185 阅读 · 0 评论 -
Effective C++ 读书笔记 Item50 为什么需要自定义new和delete?
我们在Item 49中介绍了如何自定义new的错误处理函数,以及如何为你的类重载operator new。 现在我们回到更基础的问题,为什么我们需要自定义operator new或operator delete?检测使用错误。new得到的内存如果没有delete会导致内存泄露,而多次delete又会引发未定义行为。如果自定义operator new来保存动态内存的地址列表,在delete中判断...原创 2019-08-27 13:55:02 · 161 阅读 · 0 评论 -
Effective C++ 读书笔记 Item 49 new handler的行为
new申请内存失败时会抛出"bad alloc"异常,此前会调用一个由std::set_new_handler()指定的错误处理函数(”new-handler”)。set_new_handler()“new-handler”函数通过std::set_new_handler()来设置,std::set_new_handler()定义在<new>中:namespace std...原创 2019-08-27 11:18:26 · 167 阅读 · 0 评论 -
Effective C++ 读书笔记 Item48 了解模板元编程
模板元编程(Template Metaprogramming,TMP)就是利用模板来编写那些在编译时运行的C++程序。模板元程序(Template Metaprogram)是由C++写成的,运行在编译器中的程序。当程序运行结束后,它的输出仍然会正常地编译。C++并不是为模板元编程设计的,但自90年代以来,模板元编程的用处逐渐地被世人所发现。模板编程提供的很多便利在面向对象编程中很难实现;...原创 2019-08-27 10:12:48 · 211 阅读 · 0 评论 -
Effective C++ 读书笔记 Item47 使用Traits类提供类型信息
C++中的 Traits 类可以在编译期提供类型信息,它是用Traits模板及其特化来实现的。 通过方法的重载,可以在编译期对类型进行”if…else”判断。我们通过STL中的一个例子来介绍Traits的实现和使用。本文以iterator_traits为例介绍了如何实现traits类,以及如何使用traits类(在Item 42中提到过iterator_traits)。 其实C++标准库中...原创 2019-08-26 22:10:18 · 181 阅读 · 0 评论 -
Effective C++ 读书笔记 Item46 需要类型转换时,应当在类模板中定义非成员函数
Item 24中提到,如果所有参数都需要隐式类型转换,该函数应当声明为非成员函数。Item 24是以Rational和operator*为例子展开的,本文把这个观点推广到类模板和函数模板。 但是在类模板中,需要所有参数隐式转换的函数应当声明为友元并定义在类模板中。模板化的Rational既然是Item 24的推广,那么我们先把Item24中的Rational和operator*模板化。得到...原创 2019-08-26 21:09:05 · 184 阅读 · 0 评论 -
Effective C++ 读书笔记 Item30 透彻了解 inlining 的里里外外
inline(内联)函数的好处太多了:它没有宏的那些缺点,见Item 2:避免使用define;而且不需要付出函数调用的代价。 同时也方便了编译器基于上下文的优化。但inline函数也并非免费的午餐:它会使得目标代码膨胀,运行时会占用更多的内存,甚至引起缓存页的失效和指令缓存的Miss,这些都会造成运行时性能的下降。 但是另一方面,如果inline函数足够小以至于生成的目标代码比函数调用还...原创 2019-08-22 22:58:14 · 153 阅读 · 0 评论 -
Effective C++ 读书笔记 Item29 追求异常安全的代码
考虑下面例子,有一个菜单类, changeBg 函数可以改变它的背景,切换背景计数,同时提供线程安全:class Menu{ Mutex mutex; //提供多线程互斥访问 Image *bg; //背景图片 int changeCount; //切换背景计数public : void changeBg(istream& sr);}; ...原创 2019-08-22 21:21:24 · 157 阅读 · 0 评论 -
Effective C++ 读书笔记 Item28 不要返回对象内部的句柄
不要返回对象私有成员的句柄。这里的“句柄”(handle)包括引用、指针和迭代器。 这样可以增加类的封装性、使得const函数更加const, 也避免了空引用的创建(dangling handles)。句柄就是个数字,一般和当前系统下的整数的位数一样,比如32bit系统下就是4个字节。这个数字是一个对象的唯一标示,和对象一一对应。这个对象可以是一个块内存,一个资源,或者一个服务的contex...原创 2019-08-22 20:44:29 · 143 阅读 · 0 评论 -
Effective C++ 读书笔记 Item27 尽量少做转型(类型转换)动作
C++的类型检查只在编译时执行,运行时没有类型错误的概念。 理论上讲只要你的代码可以编译那么就运行时就不会有不安全的操作发生。 但C++允许类型转换,也正是类型转换破坏了理论上的类型系统。在C#,Java等语言中类型转换会更加必要和频繁,但它们总是安全的。C++则不然, 这要求我们在类型转换时格外小心。C++中的类型转换有三种方式:C风格的类型转换:(T) expression...原创 2019-08-22 19:43:44 · 133 阅读 · 0 评论 -
Effective C++ 读书笔记 Item26 为什么要推迟变量的定义?
这一规则在任何编程语言中都适用,一方面可以避免无用的构造使得程序更高效,另一方面作用域的缩小会使程序更加清晰。存在控制流转移的代码中,你可能会不经意间定义无用的变量。例如:string encryptPassword(const string& password){ string encrypted; if (password.length() < Minim...原创 2019-08-22 17:46:40 · 94 阅读 · 0 评论 -
Effective C++ 读书笔记 Item39 明智而审慎地使用 private 继承
Item 32提出public继承表示"is-a"的关系,这是因为编译器会在需要的时候将子类对象隐式转换为父类对象。 然而private继承则不然:class Person { ... };class Student: private Person { ... }; // inheritance is now privatevoid eat(const Person& p...原创 2019-08-24 23:17:07 · 204 阅读 · 1 评论 -
Effective C++ 读书笔记 Item38 通过组合表示"拥有"或"以...实现"的关系
一个类型包含另一个类型的对象时,我们这两个类型之间是组合关系。组合是比继承更加灵活的软件复用方法。Item 32提到public继承的语义是"is-a"的关系。对象组合也同样拥有它的语义:就对象关系来讲,组合意味着一个对象拥有另一个对象,是"has-a"的关系; 就实现方式来讲,组合意味着一个对象是通过另一个对象来实现的,是"is-implemented-in-terms-of"的关系。...原创 2019-08-24 22:51:33 · 161 阅读 · 0 评论 -
Effective C++ 读书笔记 Item37 绝不重新定义继承而来的缺省参数值
不要重写父类函数的默认参数。Item 36已经说明子类中不应该重写继承而来的父类的非虚函数。 那么本文讨论的内容其实是:不要重定义虚函数的默认参数。为什么呢? 因为虽然虚函数的是动态绑定的,但默认参数是静态绑定的。只有动态绑定的东西才应该被重写。静态绑定与动态绑定静态绑定是在编译期决定的,又称早绑定(early binding);动态绑定是在运行时决定的,又称晚绑定(late bindin...原创 2019-08-24 21:18:33 · 153 阅读 · 0 评论 -
C++ primer学习笔记 第十五章 面向对象程序设计
OOP:概述面向对象程序设计(object-oriented programming)的核心思想是数据抽象、继承和动态绑定。 继承(inheritance): 通过继承联系在一起的类构成一种层次关系。 通常在层次关系的根部有一个基类(base class)。 其他类直接或者简介从基类继承而来,这些继承得到的类成为派生类(derived class)。 基类负责定义在层次关系中所...原创 2019-08-02 13:52:05 · 284 阅读 · 0 评论 -
C++ primer学习笔记 第十四章 重载运算与类型转换
基本概念重载运算符是具有特殊名字的函数:由关键字operator和其后要定义的运算符号共同组成。 当一个重载的运算符是成员函数时,this绑定到左侧运算对象。动态运算符符函数的参数数量比运算对象的数量少一个。 只能重载大多数的运算符,而不能发明新的运算符号。 重载运算符的优先级和结合律跟对应的内置运算符保持一致。 调用方式: data1 + data2; operator+(da...原创 2019-07-31 22:04:56 · 225 阅读 · 0 评论 -
C++ primer学习笔记 第九章 顺序容器
顺序容器概述顺序容器(sequential container):为程序员提供了控制元素存储和访问顺序的能力。这种顺序不依赖于元素的值,而是与元素加入容器时的位置相对应。顺序容器类型容器类型 介绍 vector 可变大小数组。支持快速随机访问。在尾部之外的位置插入或删除元素可能很慢。 deque 双端队列。支持快速随机访问。在头尾位置插入/删除速度很快。 l...原创 2019-07-27 13:45:33 · 242 阅读 · 0 评论 -
C++ primer学习笔记 第三章 字符串、向量和数组
using声明使用某个命名空间:例如using std::cin表示使用命名空间std中的名字cin。 头文件中不应该包含using声明。string标准库类型string表示可变长的字符序列。 #include <string>,然后using std::string; string对象:注意,不同于字符串字面值。 s.emtpy()是否为空; s.size(...原创 2019-07-23 14:18:22 · 185 阅读 · 0 评论 -
C++ primer学习笔记 第八章 IO库
前面章节已经在用的IO库设施istream:输入流类型,提供输入操作。 ostream:输出流类型,提供输出操作 cin:一个istream对象,从标准输入读取数据。 cout:一个ostream对象,向标准输出写入数据。 cerr:一个ostream对象,向标准错误写入消息。 >>运算符:用来从一个istream对象中读取输入数据。 <<运算符:用来向一个...原创 2019-07-26 22:18:12 · 430 阅读 · 0 评论