猫猫哥

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
//############################################################################
/* 隐式类型转换 
 *
 * 类型转换可分为:
 *                                          隐式       显式
 * 标准类型转换                        A            B
 * 用户定义类型转换                  C            D
 *                                      (casting)
 *
 *
 * A: 隐式标准类型转换
 */
   char c = 'A';
   int i = c;  // 整型提升

   char*  pc = 0;  // int -> Null pointer

   void f(int i);
   f(c);       

   dog* pd = new yellowdog();  // 指针类型转换


/* 
 * C: 隐式用户定义类型转换
 *
 * 在类内定义
 *
 * 转换 1: 将其他类型对象转成当前类型的对象
 *    - 具有可以接收一个参数的构造函数
 * 转换 2: 将当前类对象转换成其他类型
 *    - 使用类型转换函数
 */
class dog {
   public:
      dog(string name) {m_name = name; }  // NO explicit,单个参数的构造函数,如果没有显式地explicit,它同时也是类型转换函数
      // 如果不想隐式地定义类型转换,加上explicit
      string getName() {return m_name;}
  private:
      string m_name;
};

void main ()
{
  string dogname = "Bob";
  dog dog1 = dogname;
  printf("My name is %s.\n", dog1.getName());
}

OUTPUT:
My name is Bob


/* 原则: 使接口易于正确使用,不易错误使用
 * 理想情况,无法编译通过
 *
 * 一般指导原则: 
 *    1. 避免定义看起来不期望的转换
 *    2. 避免双向隐式转换,会出现二义性
 */


//转换 2:
//operator string () const { return m_name; }
// string str = dog1;
//


/* 隐式类型转换在处理数值类型的类时很有用
 * 比如分数类
 */
class Rational {
	public:
      Rational(int numerator = 0, int dennominator = 1):
               num(numerator),den(denominator) {}
      int num;  // Demo only, public data members are not recommended
      int den;

      const Rational operator*(const Rational& rhs) {
         return Rational(num*rhs.num, den*rhs.den);
      }
};

int main ()
{
    Rational r1 = 23;
    Rational r2 = r1 * 2;
}

//   Rational r3 = 3 * r1; //如果要想使用需要定义非成员函数版本运算符函数
const Rational operator*( const Rational& lhs, const Rational& rhs) {
    return Rational(lhs.num*rhs.num, lhs.den*rhs.den);
}

// 如果同时定义了类对象到外部类型的转换:
      operator int () const { return num/den; }
      // 会出现二义性
posted on 2018-12-24 02:02  猫猫哥  阅读(531)  评论(0编辑  收藏  举报