Effective C++
如果你没看过EffecitiveC++却认为自己对C++无所不知,恐怕你得三思。
W2155
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
条款14:在资源管理类中小心拷贝行为
像shared_ptr,每次拷贝的时候引用技术+1,析构的时候-1,引用计数为0时删除对象。如果你是一个资源管理类的作者,那么一定会面对一个问题,RAII在被赋值的时候会发生什么?就像lock_gurad,管理锁的一个类,他的拷贝构造是被禁止的。涉及到智能指针,那拷贝的资源一定需要进行深拷贝。移动所有权之后ptr变为nullptr。有四种解决方案供你选择。像unique_ptr。4.转移资源的所有权。原创 2025-04-18 18:00:51 · 174 阅读 · 0 评论 -
条款13:以对象管理资源
当然现在auto_ptr已经被淘汰了,C++11之后 unique_ptr完全代替了auto_ptr,unique_ptr 不仅支持指向数组,还支持自定义删除器都是auto_ptr不具备的,而且 c++17之后auto_ptr被完全删除。如果你的delete语句在循环中,遇到goto 和 break之后你的pI还能不能被释放?没错但是内存只是我们需要管理众多资源的一种,资源还包括数据的连接,文件描述符,互斥锁,网络套接字,不管哪种资源他都是从系统中获取的,当你不在需要他的时候是要还给系统的。原创 2025-04-18 17:42:36 · 231 阅读 · 0 评论 -
条款12:复制对象时勿忘其每一个一个成分
如果你声明自己的拷贝函数,再你增加成员变量的时候,不要忘记修改拷贝函数,因为即使你忘记再你的拷贝函数中添加新的成员变量,编译器并不会报错,在vs2022中会存在警告。一个好的面向对象系统会将内部封装起来,只留两个函数负责拷贝,在必要的时候编译器会自动为我们生成拷贝函数,这些编译默认生成的拷贝函数的行为就是将类的成员全部拷贝一份。这个拷贝函数看着没啥问题,实则问题大了,那我问你 你的基类成分去哪了?你的基类成分难道不需要拷贝吗?如果忘记在拷贝构造中添加date 会出现一个警告,但是拷贝赋值不会出现警告。原创 2025-04-18 16:45:06 · 220 阅读 · 0 评论 -
条款10:令operator=返回一个reference to *this
这个只是一个协定,如果你没有更好的理由,还是要遵守这个协定,像内置类型看齐。这么做是为了支持,像内置类型那样进行连锁赋值。原创 2025-04-18 08:56:34 · 109 阅读 · 0 评论 -
条款09:不要再构造函数和析构函数中调用虚函数
在构造和析构函数中调用虚函数,本身就是一个错误的行为,这样调用不会带来你想要的结果。原创 2025-04-18 08:48:51 · 218 阅读 · 0 评论 -
条款02:尽量以const,enum,inline代替#define
定义const指针时,别忘了指针指向的内容也是不可更改的,所以要在*号的后面加个const。private:首先#define不提供任何的封装所以无法作为类的专属变量。在定义 static const int NumTurns = 5;时如果你的编译不支持在类内进行初始化,可以使用匿名枚举(enum hack)或者 类内定义类外初始化。原创 2025-04-17 11:44:03 · 321 阅读 · 0 评论 -
条款03:尽可能多使用const
非const类型的指针 对应 iterator, const 类型的指针对应 const_iterator.当然这种做法需要借助 mutable关键字来释放,非静态成员变量的位常量性,是其支持逻辑常量性。这种说法主张,在const成员函数中某些变量是可以被修改的,但这些修改一定是不可见。const 放在 * 号的左边是修饰指向的内容, 放在* 右边是修饰指针本身。注意:如果成员变量中含有指针,那么这个这个指针指向的内容是可被修改的。这种说法主张的是const成员函数的任何一个比特位都是不可以修改。原创 2025-04-17 14:28:06 · 360 阅读 · 0 评论 -
条款04:确定对象被使用之前已经被初始化
一定要使用构造函数初始化列表,而不是在构造函数的函数体内赋值。private:// 不要这样private:成员初始化的顺序,就是类内声明的顺序。当一个成员变量初始化,需要用到另一个成员变量,要保证初始化的次序。例:array数组初始需要大小,在array初始化之前 保证表示大小的那个成员已经初始化完毕。原创 2025-04-17 15:30:45 · 226 阅读 · 0 评论 -
条款05:了解C++默默编写并调用哪些函数
当成员函数有引用 或者 被const修饰,编译器是不会自动生成 operator= 的,因为 &必须在定义的时候初始化,而且初始化之后不可以进行修改,const也同样,这个时候需要程序员手动写operator=。operator=被声明为私有,派生类生成的默认operator=回去先调用基类类的operator=,但是没有权限,编译器也无能为力。如果程序员不去写这些函数 ,他们会在被调用的时候由编译器生成。这些默认生成的函数都是public和inline。原创 2025-04-17 17:15:22 · 340 阅读 · 0 评论 -
条款06:若不想使用编译器自动生成的函数,就该明确拒绝
protect:private:编译自动生成的拷贝构造,会去先调用基类的拷贝构造,但是基类拷贝构造在派生类是无法访问的,这样编译器就无法默认生成了。原创 2025-04-17 17:40:32 · 275 阅读 · 0 评论 -
条款07:为多态基类声明一个virtual析构函数
就出现大问题了,当delete一个对象时,会调用其析构函数,但是ptk指向的是一个派生类对象,delete ptk;只会调用 ~Timekeeper(),而派生类部分仍然存在,这个时候就会出现一个,销毁了一半的怪物。virtual不是胡乱加的,如果一个类成员是 两个整形的变量,那么这个类的大小是64bit,如果你添加了一个虚函数,在类空间的起始位置会添加一个虚表指针,如果是32位的机器类的大小是96bit,如果是64位机器类的大小来到了128bit。客户使用你的代码时,只想使用时间,不关系是如何计时的。原创 2025-04-17 19:45:30 · 251 阅读 · 0 评论 -
条款08:别让异常逃离析构函数
C++并不禁止析构函数抛出异常,但是不鼓励你去这么做在doSomething执行完毕,v会销毁调用 widget的析构函数,如果析构函数出现异常,假设v有10个 widget对象,那么就会连抛10个异常,上个异常可能还没处理完,再抛异常程序会调用std::terminate()直接终止程序。如果你的析构函数需要执行一个动作,但是这个动作可能抛出异常怎么办?原创 2025-04-17 20:23:39 · 231 阅读 · 0 评论
分享