![](https://img-blog.csdnimg.cn/20201014180756754.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
读书笔记
木头刀
非科班,自学狗
展开
-
[读书笔记] 关于Windows的结构化异常处理SEH(二)
上篇说的是终止处理程序,这篇接着看异常处理。 也就是: __try { // 被保护的代码 } __except(exception filter/*异常过滤程序*/) { // 异常处理程序 } 与终止处理程序不同,异常过滤程序与异常处理程序主要是操作系统负责执行的,另外,在try块中的return,goto等语句不会导致像在终止处理程序中的那种局部展开,所以不会有额外的开销,其实原创 2015-04-24 16:58:43 · 418 阅读 · 0 评论 -
读书笔记《Effective c++》 条款16 成对使用new和delete时要采用相同形式
这个没什么好说的了,如果你在new表达式中使用[],必须在相应的delete表达式中也使用[]。如果你在new表达式中不使用[],一定不要在相应的delete表达式中使用[]。 因为数组的内存布局和普通对象的内存布局不同,混用是UB,具体的布局和编译器实现有关,不过多讨论。原创 2018-01-09 17:58:35 · 141 阅读 · 0 评论 -
读书笔记《Effective c++》 条款18 让接口容易被正确使用,不易被误用
a.提供给客户的接口,最好能在编译器就检查出错误。例如给参数限定有限制的类型。 b.自定义类型的接口尽量与内置类型兼容,降低客户理解成本和出错风险。 c.接口如果要求客户记住某件事,那么这个接口就有着“不正确使用”的倾向,因为客户很可能会忘记那件事。 例如,指向数组的只能指针的例子,下面的写法有两个要点: 1.返回的是智能指针,不需要客户去delete。 2.原创 2018-01-09 21:23:33 · 186 阅读 · 0 评论 -
读书笔记《Effective c++》 条款17 以独立语句将newed对象置入智能指针
假设有一个函数: int priority(); void processWidget(std::share_ptr pw, int priority1); 调用的时候可能会这么写: processWidget(std::share_ptr{ new Widget }, priority()); 在调用processWidget之前,编译器必须创建代码,做以下三件事:原创 2018-01-09 19:59:07 · 163 阅读 · 0 评论 -
读书笔记《Effective c++》 条款14 在资源管理类中小心copying行为
当持有资源的类进行copying动作的时候要注意,指向资源的指针(假定是指针)也被复制了,也就是指向资源的指针数量又1个变为2个,那么资源什么时候释放就是个必须关心的问题了。 还好shared_ptr可以解决这个问题,将指向资源的指针换成是shared_ptr指针,这样,我们不需要关心具体什么时候释放资源,因为在所有shared_ptr都失效之后资源会自动释放。 而且,shared_p原创 2018-01-09 17:27:26 · 160 阅读 · 0 评论 -
读书笔记《Effective c++》 条款13 以对象管理资源
所谓资源就是,一旦用了它,将来必须还给系统。 本书出版较早,所以书中介绍的是auto_ptr和tr1::shared_ptr,而在现在c++11中完善了原来的auto_ptr,增加了几种智能指针,这方面资料很多,这里只引用别人的一篇文章: http://blog.csdn.net/zy19940906/article/details/50470087 智能指针就是所谓的RAI原创 2018-01-09 16:39:16 · 179 阅读 · 0 评论 -
读书笔记《Effective c++》 条款19 设计class犹如设计type
a.新type的对象应该如何被创建和销毁。new,new[],delete,delete[] b.对象的初始化和对象的赋值该有什么样的差别? c.新type的对象如果被passed by value,意味着什么?copy构造函数用来定义一个type的pass by valued该如何实现。 d.什么是新type的“合法值”?限定新type的值集。 e.你原创 2018-01-10 10:58:53 · 168 阅读 · 0 评论 -
读书笔记《Effective c++》 条款20 宁以pass-by-reference-toconst替换pass-by-value
默认情况下,c++以by value方式传递对象(函数参数、返回值),这些副本是由对象的copy构造函数产出。 传值有两个问题: a.效率低下。 b.可能产生对象切割(slicing)问题 class Base { public: virtual void test() const { cout << "base.test()" << endl; }原创 2018-01-10 14:22:46 · 142 阅读 · 0 评论 -
读书笔记《Effective c++》 条款21 必须返回对象时,别妄想返回其reference
本节举例说明了函数返回一个对象的引用有很多坑,尤其是对这种operator*类的函数,因为客户可能会这么写:a*b*c,这样,即使在堆上分配对象,也会陷入用户无法对其调用delete的深坑,所以其实最简单的做法就是直接by value返回一个新对象,这样虽然你可以说效率不高,但是却是最安全的做法。而关于效率的问题就交给编译器吧,编译器会决定是否对你的返回值进行优化(RVO)。 不在项目初原创 2018-01-10 14:51:25 · 167 阅读 · 0 评论 -
读书笔记《Effective c++》 条款22 将成员变量声明为private
本节主要是可见性和封装的问题。 结论: a.切记将成员变量声明为private。这可赋予客户访问数据的一致性、可细微划分访问控制、允诺约束条件获得保证,并提供class作者以充分的实现弹性。 b.protected并不比public更具有封装性。原创 2018-01-10 14:58:17 · 177 阅读 · 0 评论 -
读书笔记《Effective c++》 条款23 宁以non-member,non-friend替换member函数
本节的介绍感觉更像是内容与接口的设计实现,书中以浏览器为例,浏览器class提供一系列的功能,并封装一系列的数据,如果要增加其他内容可以在相同的名字空间内独立出不同的头文件,就像stl中的做法,例如,可以有下载头文件、工具头文件、影响头文件,而这些功能都不是直接放在class里,这是封装的另一个含义,让私有变量被更少的函数访问。 对这个我现在的理解不深,记住就好了,在实际项目中能想起还有这么一条原创 2018-01-10 15:58:12 · 217 阅读 · 0 评论 -
读书笔记《Effective c++》 条款15 在资源管理类中提供对原始资源的访问
结论: a.APIs往往要求访问原始资源,所以每一个RAIIclass应该提供一个取得其所管理的资源的办法,例如智能指针的get()方法。 b.对原始资源的访问可能经由显示转换或隐式转换。一般而言显式转换比较安全,但隐式转换对客户比较方便,当然比较常见的做法是显示转换。原创 2018-01-09 17:43:03 · 136 阅读 · 0 评论 -
读书笔记《Effective c++》 条款12 复制对象时勿忘其每一个成分
名词: copying函数 = 拷贝构造函数 + 赋值操作符 重点是:当你自己要编写一个copying函数时,请确保: a.复制所有local成员变量 b.调用所有base class内的适当的copying函数。(拷贝构造函数是在初始化列表调用base class的函数,赋值操作符是在函数体调用Base::operator=(rhs)) 另外,这两个co原创 2018-01-09 13:40:36 · 136 阅读 · 0 评论 -
[读书笔记] 关于Windows的结构化异常处理SEH(一)
结构化异常处理(一下简称SEH),实际上包含两方面的功能:终止处理(termination handling)和异常处理(exception handling),这篇笔记主要是关于终止处理,异常处理以后再看。 终止处理程序确保不管一个代码块是如何退出的,另一个代码块(终止处理程序)都能被执行。 *其实用代码表示就是 __try { // 受保护代码 } __finally {原创 2015-04-24 10:33:52 · 619 阅读 · 0 评论 -
[读书笔记]crt静态链接注意模块间内存传递
谁申请,谁释放。 VOID ExeFunc() { PVOID pv = DLLFunc(); // do somtehing via pv free(pv); } PVOID DLLFunc() { return(malloc(100)); } 上面的代码表示,在DLL的函数DLLFunc申请内存,而在Exe的函数ExeFunc()中释放,有问题吗? 不一定。 结果原创 2015-08-21 17:31:21 · 572 阅读 · 0 评论 -
读书笔记《Effective c++》 条款03 尽可能使用const
const是一种约束,告诉编译器和其他程序员,这个值不要被修改。 a.函数返回值是常量: 例如有理数的乘法重载: const Rational operator* (const Rational& lhs, const Rational& rhs);这样写可以避免一些暴行,例如 Rational a, b, c; (a * b) = c; b.const成员函数 将const实原创 2018-01-08 15:35:59 · 183 阅读 · 0 评论 -
读书笔记《Effective c++》 条款02 尽量用const,enum,inline代替#define
1.尽量用const,enum,inline代替#define 以编译器代替预处理器。 a.使用#define可能导致编译器错误信息不明显,而常量会进入符号表。 b.#define没有作用域的限定。 c.当编译器不支持类内静态常量初始化,而又必须使用此常量来定义数组时(编译器要求编译期就能计算出数组的长度),可以使用the enum hack,enmu{MAX_LEN = 50};the原创 2018-01-08 11:21:28 · 140 阅读 · 0 评论 -
读书笔记《Effective c++》 条款07 为多态基类声明virtual析构函数
这个其实不用多说,用过OO类的语言应该都要这样。 这么看来简单的对象和delphi的对象结构差不多。 书中说c++不支持final,在c++11中已经支持了,所以如果不希望类被继承,可以加上final c++的final有两个用途: 1.阻止类被继承 2.组织虚函数被override stl中的容器类之类的按说应该都是final的,他们没有虚析构函数,所以不应该继承他们原创 2018-01-08 21:07:38 · 126 阅读 · 0 评论 -
读书笔记《Effective c++》 条款08 别让异常逃离析构函数
析构函数抛出异常会导致后面的清理资源语句得不到机会执行,会导致资源泄漏。 结论: a.析构函数绝对不要吐出异常。如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下(不传播)他们或者结束程序。 b.如果客户需要对某个操作函数运行期间抛出异常做出反应,那么class应该提供一个普通函数(而非在析构函数中)执行该操作,例如: 对于一个连接对象DBConnect他应该公开原创 2018-01-08 21:30:34 · 155 阅读 · 0 评论 -
读书笔记《Effective c++》 条款09 绝不在构造和析构函数中调用virtual函数
这点确实要注意,这个和delphi中是不一样的,不过也可以理解成delphi的create函数并不等同于c++的构造函数。 using std::cout; using std::endl; using std::string; class A { public: A() { test(); } protected: virtual void test() const {原创 2018-01-08 21:56:57 · 161 阅读 · 0 评论 -
读书笔记《Effective c++》 条款10 令operator= 返回一个reference to *this
这个主要的点是,赋值可以写成连锁形式: int x, y, z; x = y = z =15; class Widget { public: Widget& operator+=(const Widget& rhs) { //... return *this; } Widget& operator=(int rhs) { //... return *this; }原创 2018-01-09 09:49:26 · 114 阅读 · 0 评论 -
读书笔记《Effective c++》 条款11 在operator= 中处理“自我赋值”
例如:*px = *py 而px和py指向同一个对象,就出现了自我赋值 class Bitmap{}; class Widget { //... private: Bitmap* pb; }; //下面是operator=的实现代码 Widget& Widget::operator=(const Widget& rhs) { // 通常是在这里加一个“证同测试”,但是这还是不具备“异常安原创 2018-01-09 10:39:21 · 163 阅读 · 0 评论 -
读书笔记《Effective c++》 条款24 若所有参数皆需要类型转换,请为此采用non-member函数
这节的例子很简单,就是类外定义操作符重载,一个二元操作符,对于本身出现在操作符的右边的表达式,是需要定义一个两个参数的non-member重载的,这个和是否是需要类型转换并没有绝对的关系,我还是没有get到本小节的点。 结论: 如果你需要为某个函数的所有参数(包括被this指针所指的那个隐喻参数)进行类型转换,那么这个函数必须是个non-member。原创 2018-01-10 16:34:09 · 223 阅读 · 0 评论