C++转换函数和隐式类类型转换

来源:互联网 发布:淘宝店开店 编辑:程序博客网 时间:2024/06/04 17:56
  • 基础类型转换
  • 基础类型转为类类型
  • 类类型转换为基础类型

1、基础类型转换
基础类型之间的类型转换,满足从低精度向高精度的自动转换,规则如下:
(char -> short)-> int -> unsigned int -> long -> unsigned long -> float -> double
这种转换相对简单,这里不再细谈。

2、隐式类类型转换--基础类型->类类型
适用对象:非explicit的单参数构造函数(non-explicit-one-argument ctor)

如果构造函数只接受一个参数,则它实际上定义了转换为此类类型的隐式转换机制,有时我们把这种构造函数称为转换构造函数。
在转换中只允许一步类类型的转换。
示例:
//构造函数
Sales_data(const std::string &s);
//函数原型
Sales_data& combine(constSales_data&);
...
string null_book("9-999-99999-9"); 
//构造一个临时的Sales_data对象,实现了string到Sales_data的类型转换
item.combine(null_book) //正确

下面是一个比较完整的例子: 
//non-explicit-one-argument ctorclass Fraction{public://non-explicit-one-argument ctor//one-argument:只要一个实参就够了,给两个也可以。two-parameter//non-explicit:没有添加explicit修饰//可以把int隐式的转换为FractionFraction(int num, int den = 1)//这种默认是符合数学上的规定:m_numerator(num), m_denominator(den) {}Fraction operator+(const Fraction& f) {return Fraction(1,2);}private:int m_numerator;//分子int m_denominator;//分母};Fraction f(3, 5);double d = f + 4;//编译器首先是去找operator+函数,找到了//但是,此operator+()不匹配。//然后看int是否可以转换为Fraction。//调用non-explicit ctor将4转为Fraction f(4, 1)//然后调用operator+

通过将构造函数声明为explicit可以阻止隐式转换。
关键字explicit只对一个实参的构造函数有效。explicit的单参数构造函数(explicit-one-argument ctor)
示例:
explicit Sales_data(const std::string &s);
item.combine(null_book)//错误
explicit构造函数只能用于直接初始化。不允许编译器执行其它默认操作(比如类型转换,赋值初始化)。

标准库中含有单参数的构造函数:
接受一个单参数的const char*的string构造函数不是explicit的;
接受一个容量参数的vector构造函数是explicit的。
下面是一个较完整的示例代码:
//explicit-one-argument ctorclass Fraction{public://关键字explicit//明确制定ctor只能在直接初始化的时候可以调用//不允许编译器自动的进行类型转换explicit Fraction(int num, int den = 1):m_numerator(num), m_denominator(den) {}//转出去,把Fraction转换为doubleoperator double() const {return (double)m_numerator / (double)m_denominator;}Fraction operator+(const Fraction& f) {int fenzi = m_denominator*f.m_numerator + f.m_denominator*m_numerator;int fenmu = m_denominator*f.m_denominator;return Fraction(fenzi, fenmu);}private:int m_numerator;//分子int m_denominator;//分母};Fraction f(3, 5);double d = f + 4;//explicit关键字不允许编译器从int到Fraction的转换//Fraction可以转换到double,执行double+double

3、conversion function,转换函数--类类型->基础类型

(1) 转换函数必须是类方法
(2) 转换函数不能返回指定类型
(3) 转换函数不能有参数

转换函数使用的示例代码如下: 
//conversion function,转换函数class Fraction{public:Fraction(int num, int den = 1) :m_numerator(num), m_denominator(den) {}//转出去//转换函数,不一定是基本类型,只要有定义即可//可以把这种东西(Fraction)转换为别的东西(double)operator double() const { return (double)m_numerator / (double)m_denominator;}private:int m_numerator;//分子int m_denominator;//分母};Fraction f(3, 5);double d = 4 + f;  //编译器首先是去找operator+()函数,没找到//然后去找转换函数,找到了//编译器会调用operator double()将f转为double