一, operator = 与 copy construct function的调用时机区别
class fi {
public:
  fi() { i = 2; }
  fi( const fi & s )
   {
     i = s.i * s.i;
   }
  const fi& operator= ( const fi & s  )
     {
         if ( &s != this )  //一般都要检查是不是给自身赋值,有的情况下给自身赋值会带来一些问题
         {
            i = s.i;
         }
          return *this;
      }
private:
   int i;
};

如下调用:
  fi a;      //default construct, a.i = 2
  fi b = a; //copy construct, not operator =   ( b.i = 4 )
  b = a;   // operator =  ( b.i = 2)
结论: 对象被定义的时候,一定是调用 构造函数——无论是缺省构造,还是拷贝构造函数,具体取决于对象从哪里初始化。

最后一个特殊的运算符定义:
  前缀的++和后缀的++(前缀的--和后缀的--也一样)
  ++a 调用  operator++(a)
  a++ 调用  operator++(a, int )
以上是对全局定义而言的,如果是定义成了member operator,那调用的就是
 ++a 调用  operator++()
  a++ 调用  operator++( int )
以上的 int 其实在函数中是没有什么用的,就是编译器用来区分这两种形式调用的一个哑元

二,自动类型转换
  1,特殊类型的构造函数。
  假设有如下的函数f,以及one和two类定义。
  class one{
    public:
      one(){};
};
  class two {
  public:
  two( const one&){}
};
  one o1;
  two o2;
  void f( two );
  那么f( o2 )调用肯定没有问题。f( o1 )呢?也没有,因为编译器会自动将one转换成two( 由于two( const one &)构造函数的存在 ),这就是自动转换之一。
   如何组织这种自动转换?只要将 two( const one&){} 改成 explicit two( const one&){}即可,这样就可以了,那么调用只能改为,f(  two(o1)  ) ,这样我们手动做了编译器的工作了,因为编译被告知:不能使用那个构造函数执行任何的自动转换。
     那么除了上面的这种特殊构造函数外,还有没有另外的一个方法呢?这就是运算符重载。
2,运算符重载。
    自动类型转换的第2种方法就是运算符重载。通过 operator 后面跟上要转换的类型,就可以将当前类型转换为所想要的。这种方法非常独特: 这个成员函数的运算符重载没有指定返回类型,它的返回类型就是:我们希望重载的运算符的名字。
    class two {
  public:
  // two( const one&){}
};
  class one{
    public:
      one(){};
      operator two() const { return two(); }
};
 void f( two );
   总结:
  这两种转换的区别:
   构造函数: 目的类进行转换。
   运算符重载: 原类进行转换,并且可以实现从用户自定义类型向内置类型转换
。例如:
class three{
 public:
  three():i(0){}
  three( int I ): i( I ){}
  operator int () const { return i; }
 private:
  int i;
 };

 void fun1( int i );

 fun1( 100 );
three obj( 90 );
 fun1( obj );      //合法,可以向内置类型转换

posted on 2007-08-16 09:21  Frodo  阅读(223)  评论(0编辑  收藏  举报