存档

文章标签 ‘复制控制’

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

2012年2月29日  1,973 views 没有评论

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);//二元操作符重载时第一个参数为左操作数,第二个参数为右操作数。

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

成员与非成员


成员或非成员实现 :

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

成员与非成员


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

阅读全文…

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

2012年2月29日  3,060 views 3 条评论

13章复制控制


编写自己的复制构造函数时,必须显式复制需要复制的任意成员。显示定义的复制构造函数不会进行任何自动复制。


即使对象赋值给自己,赋值操作符的正确工作也非常重要。保证这个行为的通用方法是显式检查对自身的赋值。最需要注意的是在赋值的时候做操作数的删除操作,如果不进行检查,
可能会出现先删除之后又将已经删除掉的数据赋值给做操作数,造成数据丢失。