随笔 - 55  文章 - 15  trackbacks - 0
<2012年6月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用链接

留言簿

随笔分类

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜

运算符重载的目的:使操作更明确,更方便
可以是成员函数,也可以是全局函数。成员函数的好处是:返回值可以调用函数。全局函数的好处是:运算符两边的对象都可以进行隐式类型转化。但是,如果定义了一个全局的运算符,将有机会覆盖掉标准的运算。
不能重载的运算符:
1. 成员选择operator.()。如果允许重载,就不能用普通的方法访问成员,只能用operator->()访问。
2. 成员指针间接引用operator.*()。
3. 不存在的用户自定义的运算符。
ps:不能改变优先级,也不能改变运算符的参数。否则很难记忆。
几个比较重要的运算符:

Class Byte
{
int b;
public:
 
const Byte& operator++()// prefix ++byte
 {
    b
++;
    
return *this;
 }


 
const Byte& operator++(int)//postfix byte++
 {
    Byte before(b);
    b
++;
    
return before;
 }

}
;

/////////////
class Integer{
long i;
public:
  Integer(
long ll = 0):i(ll){}
  friend 
const Integer operator-(const Integer& left, const Integer& right);
}
;
const Integer operator-(const Integer& left, const Integer& right)
{
    
return Integer(left.i - right.i);
}
//返回值优化,构造一个对象并交给返回值。


operator->灵巧指针,是一个类看起来像指针 :必须返回一个对象(或对象的引用),该对 象也有一个指针间接引用运算符;或者必须返回一个指针。

class Obj{
 
public:
  
void f() const {cout << "f()" << endl;}
}
;
class ObjContainer{
  vector
<Obj*> a;
  friend 
class SmartPointer;
}
;
class SmartPointer{
  ObjContainer
& oc;
  
int index;
public:
  SmartPointer(ObjContainer
& objc):oc(objc){
     index 
= 0;
   }

  Obj
* operator->()const{
     
return oc.a[index];
   }

}
;

ObjContainer oc;
SmartPointer sp(oc);
sp
->f();  

一般将智能指针嵌入它所服务的类中。

operator->*(),二元运算符,必须有一个operator(),且必须是成员函数。operator()允许里面有任意参数,使得对象看起来像一个真正的函数。
class Dog{
  
public:
   
int run(int i) const{}
   
int eat(int i) const{}


typedef 
int(Dog::*PMF)(int)const;

class FunctionObject{
  Dog
* ptr;
  PMF pmem;
 
public:
  FunctionObject(Dog
* dp, PMF pmf):ptr(dp), pmem(pmf){}
  
int operator()(int i)const{
     
return (ptr->*pmem)(i);
    }

  }
;
 FunctionObject 
operator->*(PMF pmf){
    
return FunctionObject(this,pmf);//automaticlly invoke operator()
 }

}
;

int main()
{
  Dog w;
  Dog::PMF pmf 
= &Dog::run;
  (w
->*pmf)(1);
  pmf 
= &Dog::eat;
  (w
->*pmf)(2);
  
return 0;
}

operator->*返回一个FunctionObject对象,其中有对象*this,也有指向成员的指针pmem。


赋值运算符
从有到有。
MyType b;
MyType a 
= b;//a没出现过,调用拷贝构造函数
= b;//a已经出现,调用operator=()
因为是从一个对象赋值至已有的对象,以为着这个对象不再使用,所以要进行一些处理。并且应该判断是否赋值给自己。
引用计数的引入:所有的指针都指向一块内存,所以,增加一块引用就应该增加一次计数。当计数为0时,表示没有指针指向它,可以delete掉。
但是,如果修改了这块内存,意味着所有指向它的引用都被修改了,所以出现了写拷贝。判断引用计数是否为1,为1的话说明没有其他指针指向它,可以修改。如果大于1,说明有很多指针指向它,那就重新开辟一块内存,将那块内存的内容复制过来,再进行修改,同时,指向最初内存的引用计数应该减1.

自动类型转换
转型构造函数:必须只有一个参数,隐式转换。如果想显式转换,使用explicit定义拷贝构造函数。
运算符转换:
class Three{
   
int i;
  
public:
    Three(
int ii = 0int = 0):i(ii){}
}
;

class Four{
    
int x;
  
public:
    Four(
int xx):x(xx){}
    
operator Three()constreturn Three(x);}
}
;

void g(Three){}
int main()
{
  Four four(
1);
  g(four);
  g(
1);
}



























1
                
posted on 2012-06-01 16:48 Dino-Tech 阅读(266) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理