More Effective C++ 第二部分 操作符

Posted zhangqixiang5449

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了More Effective C++ 第二部分 操作符相关的知识,希望对你有一定的参考价值。

5.对定制的”类型转换函数”保持警觉


使用类型转换函数将会导致预期之外的转型,应避免隐式的转换,使用显式转换代替。

C++可以使自定义类型增加隐式类型转换的功能,方法:
1.使用单自变量construcor。

class Name
public:
    Name(const string& s);//将string转换为Name
;

2.使用隐式类型转换操作符

class Name
public:
    operator string() const;//将Name转换为string
;

使用此类隐式类型转换将会导致:在未打算调用这些函数的时候,这些函数会被调用。解决方法是使显示的转换代替隐式的转换:
1.对于单自变量constructor使用explicit

class Name
public:
    explicit Name(const string& s);//将string转换为Name
;

Name n = static_cast<Name>("zzz");

2.对于隐式类型转换操作符使用非隐式转换函数代替

class Name
public:
    string toString() const;//将Name转换为string
;

string s = name.toString();

6.区别increment/decrement操作符的前置(prefix)和后置(postfix)形式

incrrement指++,decrement指–,前置指++a这样的语句,后置指a++。
C++支持重载前置和后置的++,--,以下内容以++说明。

class UPInt
public:
    UPInt& operator++();//前置式++
    const UPInt operator++(int);//后置式++,其参数并没有意义,仅用来区分前置和后置。
;

后置式返回const类型的原因是避免出现这样的代码:

UPInt i;
i++++;//因为const对象不能调用non-const member function,所以报错。

使用后置式++会导致产生临时对象,需要一次构造与析构成本,而前置式并没有产生临时对象。所以从效率角度来讲应该优先使用前置式++。


7.千万不要重载&& ||和,操作符


重载&& ||和,操作符无法令其行为如原有的操作符那样

骤死式评估方式:

if(a && b)

在上面的语句中,若a为0那么b不会执行,若b是一个函数。很多程序依赖这样的逻辑来实现。如:

if( p != null && p->doSomething() )

||也是一样。若我们重载了&&或||将丧失这样的语义,因为相当于调用一个函数,而参数是&&左右两边的参数。所以&&和||右边的内容都会被执行。这样无法提供客户所预期的某种行为。

逗号操作符:逗号左侧先评估,右侧再被评估,整个逗号表达式的结果以逗号右侧的值为代表。

for(int i = 0,j = 10; i < j; ++i,--j)//使用逗号表达式的例子。

重载后的逗号表达式无法控制评估顺序,也就是说重载了,后的a,b并不确定a还是b会先执行。


8.了解各种不同意义的new和delete

new operator

new operator为常见的new字符。他用来分配内存(使用operator new),并调用constructor。

operator new

operatop new用来分配内存,接收第一个参数为size_t类型,可以加上其余的额外参数,返回空指针类型。可以被重载。

void* operator new(size_t size);
void* rawMemory = operator new( sizeof( someClass));//可直接调用

Placement new

Placement new用来在一块分配好的内存上使用constructor。
使用方法(需要包含new):

#include <new>
class Widget
public:
    Widget(int WidgetSize);
;
Widget* consructWidgetInBuffer(void* buffer,int widgetSize)
    return new (buffer) Widget(widgetSize);

void* operator new(size_t,void *location)
    return location;

/*
其中new (buffer) Widget(widgetSize);为new operator的一种调用方式,其中buffer作为new operator调用operator new时所用。buffer传递给了location。
*/

delete

new operator使用delete operator来销毁,不止释放内存,还调用析构函数:

auto a = new someClass();
delete a;

operator new使用operator delete来销毁,只释放内存,相当于C的malloc和free:

void* buffer = operator new(50 * sizeof(char));
operator delete(buffer);

placement new使用destructor,因为内存并非由operator new分配而来,应该调用分配这块内存队员的释放函数:

void* mallocShared(size_t size);
void freeShared(void memory);

void sharedMemory = mallocShared(sizeof(Widget));
Widet *pw =cnstructWidgetInBuffer(sharedMemory,10);

pw->~Widget();//调用析构函数,但是并未释放内存
freeShard(pw);//释放内存

以上是关于More Effective C++ 第二部分 操作符的主要内容,如果未能解决你的问题,请参考以下文章

More Effective C++ 第五部分 技术

Effective C++笔记(11)—定制new和delete

小项目实训:曹操外卖第二部分

《More Effective C++》总结笔记——异常

《More Effective C++》总结笔记

More Effective C++ 第三部分 异常