设为首页 加入收藏

TOP

C++primer读书笔记8重载操作符(一)
2015-07-20 18:05:38 来源: 作者: 【 】 浏览:6
Tags:primer 读书 笔记 重载 操作
函数的重载操作符中也有不少细节


1 重载操作符特点
重载操作符本质上就是重载函数,它的特点:
<1>除了函数调用操作符‘()’外,所有的重载操作符的形参数目必须与操作符的操作数目相等。
<2>重载操作符的操作数必须至少有一个类类型,否则就不是重载而是原型了。
<3>优先级和结合性不会发生改变,例如对于算数操作符的重载,*的优先级肯定还是大于+
<4>不具有短路求值特性(就是根据已有的值就可以判断出最终的逻辑结果的话就会停止计算)
<5>操作符可以可以是类的成员函数,或者普通的非成员函数。
区别是当是类的成员函数,那么this形参为第一个操作数
<6>重载操作符的使用,既可以像操作符之前的调用方式那样进行操作,也可以像函数调用那样。
Item item1 ,item2;
item1 + item2;		// call method 1
operator+(item1,item2)	// call method 2
// if + is operator of class
item1 + item2;
item1.operator+(item2);


2 重载操作符的谨记

<1> 赋值操作符,取地址操作符,逗号操作符
这些操作符对类类型都有默认的含义,也就是如果没有自己重载,编译器就会自己去合成这些这些操作符函数。
这些操作符都是具有自己的意义的,如果我们自己重写就会失去原本的意义。
<2> 赋值操作‘=’,下标'[]',箭头‘->’,调用操作度‘()’必须定义为类成员,定义为类成员操作符,否则会出现变异错误。
<3>复合赋值操作符‘+=’等,一斤改变类状态的操作符自增,自减等一般也要定义为类成员
<4>对称的操作符如,算数运算符 ‘+’,‘-’,‘*’,‘%’一般最好定义为非成员操作符

3 类成员操作符
类成员操作符比非成员操作符要看起来要少一个参数,其实这个少的参数是this参数,而且他被限定为操作符的第一个操作数。


4 输入输出操作符的重载
<1>输出操作符中应该尽量包含少的格式化,因为这样可能会违背使用者要表达的意愿
<2>IO操作符必须为非成员函数
这个说一定是为了兼容对象的输出以及一般类型变量的输出。但是如果把输出操作符设置为类成员函数并没有编


译错误,并且实际上也是可行的。如下所示:
// output.h
#pragma once
#include 
  
   
using namespace std;
class Input
{
public:
Input(void);
~Input(void);
ostream& operator <<(ostream& out);
private:
string str;
int fun;
};


// output.cpp
#include "Input.h"
Input::Input(void)
{
str = "keep move on";
fun = 1001;
}
Input::~Input(void)
{
}
ostream& Input::operator<<(ostream& out)
{
out<<"persist on"<
   
    
输出结果:
persist on1001
I'll always find you

结论:这样因为对象必须作为第一个参数,如:in<

5 算数操作符的重载
算数操作符要谨记的是它返回一个新的值,不是引用,这个值是两个值计算的结果。因为如果返回的是临时变量的引用的话,临时变量会被销毁。

6 相等操作符
通常比较每个类的数据成员,如果所有的对应成员都相等,那么就认为两个对象相等。

7 关系操作符
关系操作符通常用于需要对类对象进行排序的时候,所以它和相等操作符有点不一样,例如小于操作符只需要类对象数据成员中的某一个而不是所有的,容器中的对象的相等的定义也是根据‘<’来定义的,如果 A ! !
8 赋值操作符
<1>一个类可以定义多个赋值操作符
<2>没有自己定义赋值操作符,编译器会自己定义一个
<3>赋值操作符必须返回对*this的引用,这样就不需要重新创建副本,销毁之前的版本一系列复杂的操作


9 下标操作符
C++中的容器在检索单个元素的时候一般会定义下标操作符‘[]’,因为下标操作符是跟类对象密切相关的,所以它必须定义为类的成员。定义类的下标操作符的时候,一般要定义连个版本,一个是const成员并返回const引用,一个是非const成员并且
返回引用
#pragma once
#include 
        
         
using namespace std;
class XB
{
public:
XB(void);
~XB(void);
int& operator [](const size_t index);
const int& operator [](const size_t index)const;
private:
vector
         
           data; }; //XB.cpp #include "XB.h" XB::XB(void) { data = vector
          
           (5,2); } XB::~XB(void) { } int& XB::operator [](const size_t index) { return data[index]; } const int& XB::operator[](const size_t index)const { return data[index]; } //main.cpp #include "XB.h" #include 
           
             using namespace std; void main() { XB xb; cout<
            
             
10 解引用操作符'*'和箭头操作符'->'
这两个操作符经常用在智能指针上面,就是把一些类对象给它赋予指针的功能。智能指针除了要操作的类外,另外包含两个类,一个类用来存放类对象的指针,以及使用计数。另一个类用来操作使用计数,并根据使用计数的大小来确定是否释放对象。下面的例子中Tv类是要操作类,TvPtr是包含使用技术和操作类的类。
#include 
              
               
using namespace std;
class Tv
{
public:
Tv(void):m_height(100),m_width(390){};
~Tv(void){};
int func(){return m_height * m_width;}
private:
int m_height;
int m_width;
};


class TvPtr
{
friend class TvPtrCnt;
Tv* sp;
size_t use;
TvPtr(Tv* p):sp(p),use(1){}
~TvPtr(){delete sp;}
};


class TvPtrCnt
{
public:
TvPtrCnt(Tv* p):ptr(new TvPtr(p)){}
TvPtrCnt(const TvPtrCnt& orig):ptr(orig.ptr){++ptr->use;};
TvPtrCnt& operator =(const TvPtrCnt &orig){++ptr->use;}
~TvPtrCnt(){if(--ptr->use ==0) delete ptr;}


Tv& operator*(){return *ptr->sp;}
Tv* operator->(){return ptr->sp;}
const Tv& operator*()const{return *ptr->sp;}
const Tv* operator->()const{return ptr->sp;}
private:
TvPtr* ptr;
};
void main()
{
Tv *p = new Tv();
TvPtrCnt zp(p);
std::cout<<(*zp).func()<
               
                func()<
                
                 
注意:这里说的是箭头操作符‘->’它不同于一般的操作符,就那point->action来讲:
<1>如果point是指针,指向具有action成员的对象,那么编译器将代码编译为调用该对象的action的成员
<2>如果action是定义了‘->’操作符的类的一个成员,那么point->a
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++primer读书笔记9转换与类类型 下一篇hdu 1166线段树

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: