Quantcast
Channel: 代码至上 - Codeup.org »复制控制
Viewing all articles
Browse latest Browse all 2

【笔记迁移】C++Primer笔记 2010/9/8

0
0

13章复制控制


智能指针类的实现是通过使用计数类来管理指针成员的。计数类将指针成员再次封装,并含有一个计数器来记录有多少个对象包含这个指针成员。需要注意的是要将使用计数类的类设为友元。同时在计数类的友元类中要转换对指针的操作为对计数类的对象的操作。在复制的时候,首先将左操作数的计数类对象减一(如果计数器减一后为零,则删除对象),然后将右操作数的计数类对象赋值给做操作数,这样左右操作数共用同一个计数器类的对象,同一个指针只有一个计数器类的对象。析构函数中也要对计数类的计数器进行操作(减一,为零则删除)。

让智能指针负责删除共享对象,可以避免悬垂指针的出现。

class U_Ptr{
    friend class HasPtr;
    int *ip;
    size_t use;
    U_Ptr(int *p):ip(p),use(1){}
    ~U_Ptr(){delete ip;}
};//这是一个计数类的示例。

智能指针


值型类给指针成员提供值语义将对指针的操作变为对指针所指向的值的操作,复制值型对象时,会得到一个不同的新副本,对副本所做的改变不会反映在原有对象上,反之亦然。
这样就解决了所有因共享对象而产生的一系列的问题,但是同时也不可以使用共享对象了。


复制构造函数,赋值操作符,析构函数 这三者是紧密联系的,如果定义了其中一个,一般也要定义剩余的两个。这三个函数时“复制控制”函数的主要部分,
他们定义了复制、赋值或撤销该类型对象的含义,对特殊的成员进行管理。
定义复制控制函数最为困难的部分通常在于认识到他们的必要性。分配内存或其他资源的类几乎总是需要定义复制控制函数来管理所分配的资源。


14章重载操作符与转换


内置逻辑与(&&)和内置逻辑或(||)操作符使用短路求值,如果重新定义该操作符,丢失操作符的短路求值特征。


如果要将类用作关联容器键类型,则应定义<操作符和==操作符,因为许多算法假定这些操作符石存在的。例如sort算法使用<操作符,而find算法使用==操作符。
如果定义了==操作符,相应的也应该定义不等操作符!=。而如果定义了<或某个关系操作符,则应将全部四个关系操作符都定义(>,>=,<,<=)。

//重载了某个操作符,则应将其相关的其他操作符也要重载


成员与非成员操作符重载:

  • 成员操作符重载有一个默认的参数即当前对象的this指针,这是默认的左操作数,所以复制运算符=重载时只需要一个右操作数作为参数既可。ClassType& operator = (const ClassType&);
  • 当左操作数不是当前类的对象时,我们就必须使用非成员实现方式,例如输出操作符<<的左操作数应该是ostream对象。ostream& operator<< (ostream& out,const ClassType& s);//二元操作符重载时第一个参数为左操作数,第二个参数为右操作数。

一般非成员实现时要在类中显式声明此重载函数

成员与非成员


成员或非成员实现 :

  • 赋值(=)、下标([])、调用(())和成员访问箭头(->)等操作符必须定义为成员,将这些定义为非成员函数将在编译时出错。
  • 改变对象状态或与给定类型紧密联系的其他一些操作符,如自增、自减和解引用,通常应定义为成员函数。
  • 对称的操作符,如算术操作符、相等操作符、关系操作符和位操作符,最好定义为普通非成员函数。

成员与非成员


当重载输出操作符的时候所做的格式或应尽量的少尤其不要输出换行符,如果需要对输出进行格式化,我们应该让用户自己来控制输出细节。


重载输入操作符 与重载输出操作符的不同点有2点

  1. 形参表第二个形参的修饰符不同,输出操作符为const而输入操作符没有const
  2. 更重要的是,输入操作符必须处理错误和文件结束的可能性。

  • 使用输入操作符 时要进行错误检查,我们无需对每次读入都进行检查,只要在使用输入数据之前检查一次就可以了。错误检查直接使用if(istream)就可以了,如果输入期间出现错误,则istream对象为0。
  • 有时候我们还应该对流状态进行设置,但是一般只设置failbit对于badbit和eofbit最好是留给IO标准库自己来指出。iostream.setstate(failbit);//流条件状态章节 C++Primer 247页第八章标准IO库

算术操作符与关系操作符一般都定义为非成员实现,而且如果既定义了算术操作符又定义了相关复合操作符,一般应使用复合赋值实现算术操作符。
相等操作符==的定义中返回值为inline bool ,示例:

inline bool operator == (const ClassType&amp; lhs,const ClassType&amp; rhs);

不等操作符!=应该调用相等操作符来完成。示例:

inline bool operator != (const ClassType&amp; lhs,const ClassType&amp; rhs)
 { return  !(lhs == rhs) ; }

当类定义函数的时候,尤其是操作符重载函数的时候,要注意参数的const属性,有时要定义一个const版本还要定义一个非const版本。
返回值的const与否也要注意。这些都应根据类的具体使用情况来判断。
如果定义了下标操作符,通常情况下要定义const和非const两个版本。他们的函数体应该是一样的,只是在函数名声明定义时有关键字不同。
示例:

const int &operator[] (const size_t) const; //const版本
int &operator[] (const size_t);//非const版本

const版本中第一个const为返回值的修饰,第二个const为参数修饰关键字,第三个const为函数修改成员权限的修饰关键字。

const, 重载, 操作符


Viewing all articles
Browse latest Browse all 2

Latest Images

Trending Articles



Latest Images