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 篇原創文章 · 獲贊 212 · 訪問量 47萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章