![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Effective C++
SilenceHell
学生,希望能在csdn上学到知识。
展开
-
条款10:令operator=返回一个reference to *this
因为我们在写赋值时喜欢写成连等的形式,所以我们最后将返回写成reference to *this的形式。 int x,y,z; x=y=z=15; 当15被赋值给z的时候,z返回一个同类型的引用,这时就可以继续赋值给y实现连等。 以上规则适用于所有赋值相关运算。 这个规则并无强制性,但是还是遵守的好。 ...原创 2018-10-11 09:36:29 · 135 阅读 · 0 评论 -
条款8:别让异常逃离析构函数
在析构函数里面抛出异常是不好的: class Widget{ public: … ~Widget(){…} }; void doSomething() { std::vectorv; … //v这里被自动销毁 } 当v被销毁,里面的widget会被销毁,当第一个widget被销毁时抛出异常,其他的纠葛widget还是应该被销毁...原创 2018-10-10 11:52:00 · 140 阅读 · 0 评论 -
条款7:为多态基类声明virtual析构函数
1.将析构函数声明为virtual 当我们的类要作为基类的时候我们最好将其析构函数声明为virtual类型,因为当我们用基类的指针指向一个派生类,当我们要用基类指针析构掉这个派生类的时候,如果基类的析构函数不是virtual,那么最终只有基类里面声明的变量被析构掉,而派生类里面的变量很可能没被析构掉,这会导致内存泄漏问题。当我们将基类设置为virtual的时候我们利用基类指针进行析构时,基类析构函...原创 2018-10-10 11:30:36 · 132 阅读 · 0 评论 -
条款6:如果不想使用编译器自动生成的函数,就该明确拒绝他
如果我们不想实现赋值构造函数和赋值函数该怎么办呢? 如果我们不实现它,系统会给我们默认的实现它,这样让我们很难受,所以我们该怎么办呢? 实现的办法如下: class Uncopyable(){ protected: Uncopyable(){} ~Uncopyable(){} private: Uncopyable(const Uncopyable&) Uncopyable& op...原创 2018-10-10 11:03:33 · 99 阅读 · 0 评论 -
条款5:了解C++默认编写并调用哪些函数
当我们写下: class Empty{}; 系统默认为我们编写了,默认构造函数,copy构造函数,析构函数,赋值函数。 class Empty{ public: Empty(){...} Empty(const Empty&rhs){...} ~Empty(){...} Empty& operator=(const Empty& rhs){...}//一般用this代替左...原创 2018-10-10 10:43:22 · 109 阅读 · 0 评论 -
条款四:确认对象被使用前已先被初始化
当我们定义一些值的时候比如: class Point{ int x,y; } ... Point p; 上述的x,y有时候被初始化为0,有时候不会,读取未初始化的值会导致不明确的行为。所以我们要保证初始化每一个被定义的值。 1.class成员函数的初始化 对于非内置类型,我们一般采用构造函数对其进行初始化,但是有一点我们很容易忽略: ABEntry::ABEntry(const std::str...原创 2018-10-10 10:18:40 · 98 阅读 · 0 评论 -
条款三:尽可能使用const
1.定义变量时使用const char greeting[]="Hello"; char* p=greeting;//non-const pointer,non-const data const char* p=greeting;//non-const pointer,const data char* const p=greeting;//const pointer,non-const data ...原创 2018-10-10 09:29:21 · 130 阅读 · 0 评论 -
条款2:尽量以const,enum,inline替换#
例如:#define asp 1.635 这个只会在预编译的时候被处理,而不会在编译的时候被看到,所以当出现错误时系统会提示1.635的信息,而不会提示asp的信息,而当这个定义放在我们看不到的地方,我们将会奇怪我们怎么会出现1.635这个数字。 所以我们建议使用:const double asp=1.635代替上述的写法。 特许情况:1.声明指针常量的时候我们要将指针指向的数据和指针本身都声明为...原创 2018-10-09 21:46:53 · 117 阅读 · 0 评论 -
条款1
将C++看成是一个语言联邦,由四个部分组成: 1.C语言。 2.类。 3.模板。 4.STL。 以上四个部分共同构成了C++语言,但是他们四个都有各自的使用规则和偏好,所以使用C++不同的部分我们要适应不同的规则。 ...原创 2018-10-09 21:19:02 · 96 阅读 · 0 评论 -
条款12:以对象管理资源
例子: void f() { Investment *pInv=vreateInvestment();//调用factory函数 ... delete pInv; } 这个代码的问题是,当…处发生return,goto,异常时,后面的delete代码将不能被执行,那么就容易发生内存泄漏问题。 解决办法是将delete放在一个对象类,利用对象的析构函数来delete内存。 void f() { s...原创 2018-10-11 10:51:42 · 112 阅读 · 0 评论 -
条款12:复制对象时勿忘其每一个成分
1.编译器是记仇的 当我们写出我们自己的赋值构造函数时,如果我们忘记给某些成员变量进行赋值(比如五个变量,我只复制了4个),那么编译器是不忘告诉你的,编译器会编译成功。所以当我们为class添加一个新的成员变量的时候,我们需要修改构造函数和copying函数。 当发生继承时,问题会更严重,因为你继承的新类里面的构造函数将所有新的成员变量都赋值了,但是由于之前基类构造函数没有将所有值进行赋值,所以有...原创 2018-10-11 10:27:27 · 121 阅读 · 0 评论 -
条款11:在operator中处理“自我赋值”
例子:一个不安全的自我赋值 Widget& Widget::operator=(const Widget& rhs) { delete pb; pb=new Bitmap(*rhs.pb); return *this; } 上面的这段代码当自我赋值时,会发生错误,因为开始就将pb给delete了,所以*rhs.pb也没有了。 添加了一个证同测试以达到自我赋值检测目...原创 2018-10-11 10:13:51 · 198 阅读 · 0 评论 -
条款9:决不在构造和析构过程中调用virtual函数
class Transaction { public:Transaction(); virtual void logTransaction() const=0; ... } Transaction::Transaction() { ... logTransaction(); } class BuyTransaction:public Transaction { public: virtual v...原创 2018-10-10 13:06:19 · 145 阅读 · 0 评论