类类型转换

一、关键点

转换构造函数:传送门之explicit构造函数

类类型转换运算符

 

二、转换构造函数——隐式的类类型转换

转换构造函数:该构造函数只接受一个实参,它实际定义了从构造函数的参数类型向类类型隐式转换的规则

重点是:如何使用该条规则

class Sales_data {
public:
	Sales_data() = default;
	Sales_data(const string &s): bookNo(s) {}
	Sales_data(const Sales_data &item) = default;
	Sales_data& operator=(const Sales_data &item) {
		bookNo = item.bookNo;
		units_sold = item.units_sold;
		revenue = item.revenue;
		return *this;
	}
private:
	string bookNo;
	unsigned units_sold = 0;
	double revenue = 0.0;
};

int main()  
{  
	string isbn = "league";
	Sales_data book1(isbn);			//直接初始化 
	Sales_data book2 = isbn;		//拷贝初始化 
	Sales_data book3; 				
	book3 = isbn;					//string类型隐式转换为Sales_data类型 
   	return 0;  
}  

上面“book3 = isbn;”语句包含string类型向Sales_data类型的隐式转换,因为Sales_data有转换构造函数(而该函数中的参数类型为string)。

我们要想该隐式转换(即“book3 = isbn;”)失效,可以将转换构造函数指定为explicit 的,这样不仅该转换失效,拷贝初始化也将失效。

 

三、类型转换运算符

类型转换运算符:成员函数,负责将该类类型转换为其他类型

重点是:如何定义和运用、由此带来的缺漏

class A {
public:
	A(int i = 0): val(i) {}			//转换构造函数 
	operator int() const { return val; }
private:
	size_t val;
};

int main()  
{  
	A a;
	a = 2;							//int类型向A类型的隐式转换(转换构造函数使然) 
	int sum = a + 3;				//A类型向int类型的转换 (类型转换运算符使然)
	auto ans = a + 3.14;			//A类型先转换为int类型,然后内置类型转换将所得的int继续转换成double 
   	return 0;  
}  

【缺点】

如果每个类都定义了向bool的类型转换运算符,那么语句“int i = 2; cin << i;”将是合法的,istream类型的bool类型转换运算符将cin转换成bool,而这个bool值接着会被提升成int并用作内置的左移运算符的左侧运算对象。(为了避免此情况,引入了显式的类型转换运算符<类型转换运算符定义为explicit的>,编译器不会自动执行这一类型转换,但是有例外:表达式被用作条件,编译器会将显式的类型转换自动应用于它)

避免二义性转换:定义两种将同一类型转换成同另一类型的方法、类中定义了多个与算术类型相关的转换

 

 

 

 

posted @ 2017-11-15 23:43  GGBeng  阅读(415)  评论(0编辑  收藏  举报