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

  • 基础类型转换
  • 基础类型转为类类型
  • 类类型转换为基础类型

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 ctor
class Fraction
{
public:
	//non-explicit-one-argument ctor
	//one-argument:只要一个实参就够了,给两个也可以。two-parameter
	//non-explicit:没有添加explicit修饰
	//可以把int隐式的转换为Fraction
	Fraction(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 ctor
class Fraction
{
public:
	//关键字explicit
	//明确制定ctor只能在直接初始化的时候可以调用
	//不允许编译器自动的进行类型转换
	explicit Fraction(int num, int den = 1)
		:m_numerator(num), m_denominator(den) {}

	//转出去,把Fraction转换为double
	operator 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





发布了89 篇原创文章 · 获赞 210 · 访问量 47万+

猜你喜欢

转载自blog.csdn.net/i_chaoren/article/details/78807423