Effective C++
文章平均质量分 50
利用理论和实践深度学习《Effective C++》,务必掌握C++的常用编程技巧,告别C++小白。
s.feng
计算机视觉,C++
展开
-
条款33、避免遮掩继承而来的名称
基类的成员函数和派生类的成员函数不会构成重载,如果派生类有同名函数,那么就会遮蔽基类中的所有同名函数。原创 2023-10-17 23:39:19 · 115 阅读 · 0 评论 -
条款12:复制对象时勿忘其每一个成分
首先看一个demo,copy构造函数去调用赋值函数,编译器并不会报错。不过有个问题,我们知道拷贝构造函数是构造函数,也就是说利用一个已经存在对象对构建一个暂无存在的对象,结果利用赋值函数就很奇怪,因为赋值函数是把一个存在的对象赋值给另外一个存在的对象。看了好多博客都在抄书,我不明白如果是抄书的话,写博客的意义是啥?至少应该自己吃透了用自己的话讲出来吧,真是服了。这个比较简单,好理解。原创 2023-04-15 22:12:29 · 48 阅读 · 0 评论 -
条款02: 尽量以const, enum, inline替换 #define
最近在复习effective c++, 感觉工作前看的和工作后看的感觉很不一样,以前在看第二条的时候,遇到过enum hack的说法,当时压根也没留意,现在看看感觉还挺有意思的。背景假如有个需求,就是一个类中要有一个常量,所有对象都要使用的,比如pi=3.14159265358979, 这时该怎么写呢?class Draw{ const double pi =3.14;}首先这种写法在gcc-7.5的版本上是可以编译通过的。不过有个问题,理论来说pi是所有对象都会用的公共变量,所以应该是st原创 2021-09-06 00:16:27 · 160 阅读 · 0 评论 -
条款03: 尽可能使用const
C++ effective原创 2023-04-13 14:50:16 · 73 阅读 · 0 评论 -
条款04:确定对象被使用前已被初始化
自定义类这个比较简单,就是构造函数其实不是初始化,真正的初始化发生在初始化列表那里,而且初始化顺序要个申明的顺序一样。不同编译单元的non-local static对象non-local static 对象先理解这个名词的意思,在上节中我们讨论了static, 这个名词的意思就是:不是函数中的静态变量。如何应对比如我在a.cpp需要调用一个b.cpp中的对象,那么如果b的对象没有初始化,那么就会出现意外,最好的方式是利用local static.demo在c文件中定义一个函数,这样当你调原创 2022-03-15 23:34:17 · 103 阅读 · 0 评论 -
条款05、06,熟悉编译器自动生成的构造函数
3.不定义它们,可以保证成员函数和友元函数调用它们时,产生一个连接错误,将连接期错误移至编译期。1.声明了拷贝构造函数和赋值函数,阻止了编译器暗自创建的专属版本.。2.声明了private,阻止了外部对它们的调用.。原创 2022-09-21 22:59:42 · 89 阅读 · 0 评论 -
条款07:为多态基类声明virtual析构函数
而其他函数抛出异常会有确定的行为,比如如果close抛出异常会是一个确定的数字1,那么当你收到异常1你作为用户可以设置相应的处理方案,忽略或者关机或者再次尝试。但是如果是析构函数抛出异常,有可能抛出1或者不抛出,或者抛出其他的什么玩意,不具有确定性,所以唯一的方案只能是catch(…上面的代码,当析构失败的时候,析构函数就会把异常往外抛。理论来说你往外抛就抛呗,能有啥影响?上述代码可以直接捕获异常,强制结束程序,不让你出现继续运行的可能。为什么这样设计,因为只有析构函数的异常会带来。原创 2022-09-22 11:27:41 · 136 阅读 · 0 评论 -
条款08: 别让异常逃离析构函数
为什么这样设计,因为析构函数是noexcept(这里不考虑C++98),异常会导致程序终止,而其他函数抛出异常则还有抢救机会,比如如果close抛出异常会是一个确定的数字1,那么当你收到异常1你作为用户可以设置相应的处理方案,忽略或者关机或者再次尝试。注意,在C++11中,析构函数默认是noexcept的,一个noexcept的函数一旦抛出异常,程序就会直接终止的,所以目前C++11中,该条目已经有点过时了,但是下面的设计思路还是要掌握的。上面的代码,当析构失败的时候,析构函数就会把异常往外抛。原创 2023-04-14 11:00:35 · 313 阅读 · 0 评论 -
条款09: 绝不在构造和析构过程中调用virtual
testnum。原创 2023-04-14 11:07:47 · 54 阅读 · 0 评论 -
条款10,11:operator=处理方式
现在裸指针用的不多了,但是不可否认还是存在,那么这个赋值时这个ptr需要先delete到自己资源,然后在获取other的资源,这里就会有个大问题,就是你自己赋值给自己,删除资源后面还怎么弄?提前做一个认同测试,不过我再paddle框架中看只有部分赋值函数这样写,有点奇怪。类似的operator+=也可以同样操作。原创 2023-04-14 14:38:38 · 50 阅读 · 0 评论 -
条款13:以对象管理资源
文章目录思想解决方案进阶解决方案问题思想在写代码的时候,比如要申请一块内存资源,用完要释放。比如如下:int test(){ T * ptr = new T(...); do something; delete ptr;}可是有时候,当你在都something的时候出现了异常,或者提前return了,那么这个资源就没法释放。解决方案我们知道,对象在离开作用域的时候会自动调用析构函数,所以如果这个资源句柄如果是一个对象就好了,鉴于此,我们可以把句柄包装成一个对象。下面是demo:te原创 2022-03-18 15:06:48 · 310 阅读 · 0 评论 -
条款14、15 资源管理类设计时候注意事项
除了上面这种情况,还有很多使用场景,所以必须要提供一个访问原始资源的接口,有人会觉得这会破坏封装性,比如资源拿出来后被时候被释放掉了,那么资源管理对象在析构的时候就会出现问题。这个问题确实存在,其实即使不用资源管理类也会出现这个问题,而且资源管理类本来也不是负责这个事情的,所以不在此纠结。这里感觉怪怪的,就是FontHandle()被当做一个operator,这个真的是被秀到了,原来C++还有这种语法。当obj被释放后,cp所锚定的资源会消失(存疑),所以建议大家还是显式处理,骚操作总不太稳。原创 2022-09-23 20:07:53 · 393 阅读 · 0 评论 -
条款16、17,使用new的时候注意事项
这里书中举了一个小例子。上面这段代码有个问题,这个可以参考我的这篇。原创 2022-09-23 20:55:48 · 310 阅读 · 0 评论 -
条款23,24,宁以成员,友元函数,非成员
书上举例子一个operator *的例子,是有理数和整数相乘的意思,理论来说应该支持交换率,如果是成员函数,那么肯定不支持,所以设置为非成员函数,而且建议不要用友元函数。友元函数可以理解就是一个没有this指针参数的成员函数。原创 2022-09-24 13:12:50 · 87 阅读 · 0 评论 -
条款31、将文件间的编译依赖依存关系降至最低
这里可以看到main.cc 依赖person.h, 至于personimpl.h的成员变量(实现),personimpl.cc怎么改成员函数,编译的时候都不会影响main.cc, 因为没有依赖关系。在做测试的遇到一个问题,就是虚基类,析构函数要么不申明(编译器自己生成),如果申明的话一定要给一个定义,纯虚函数直接=0就行,不用再给定义。接下来是personimpl.h 和personimpl.cc。接下的main函数只要依赖接口person.h就行了.这个在设计模式专栏总结过,这里也是一个意思,具体参考。原创 2022-09-25 22:52:13 · 155 阅读 · 0 评论 -
条款32、确定public继承是is-a关系
public 继承必须是is-a关系,该论点只对public成立, 记住就行。原创 2022-09-25 23:08:26 · 93 阅读 · 0 评论 -
条款39、明智而小心的使用private继承
首先如果Widget是一个基类,后面还有人要继承,那么子类可以重新定义onTick()函数,但是这个是你不想的,所以方法二可以解决这个困扰,第二,Widget的编译依存降低,我们把WidgetTimer这个类移到外面某个文件,把成员变量timer改成指针,那么文件只要申明一个WidgetTimer就可以了,所以不会需要include "Timer.h"了,依赖降到最小。但是我只是需要这些成员去实现我的类D,并不给用户提供接口能直接访问类B的这些成员,这时候就应该用private继承。原创 2022-09-26 15:02:48 · 1010 阅读 · 0 评论 -
条款47、模板与泛型编程
这种是最简单的情况,有时候这个已经完全满足我们的需求了,但是总是有一些复杂的情况,比如现在有一个老北京鸡肉卷的食物,我们知道这个玩意里面有鸡肉,所以按照鸡肉处理就行。先说一下背景,比如我们有一些肉类事物,猪肉,羊肉,牛肉,鸡肉。这里其实就是trait的意思,但是现在元编程一般这么用的也不多, 现在用enable_if比较多。原创 2022-10-09 12:48:12 · 99 阅读 · 0 评论 -
条款46、需要类型转换时请为模板定义非成员函数
依然没有实例化,怎么办?这个代码很有意思,首先为了让所有参数可以自动类型转换,所以函数必须是non-member 函数,而由于是模板,所以在对象实例化的时候函数也必须生成,这样只能是一个friend。上面的解决方法因为是直接定义在class中,所以会暗自称为inline函数,为了减少inline的负面影响,这里可以让operator*什么都不做,调用一个外面的函数。,原因是只有一个实例化函数后才可以进行参数类型转换,但是模板函数在实例化一个函数时候都失败了,所以更不要提后续隐形类型转换了。原创 2022-10-08 21:06:39 · 174 阅读 · 0 评论