1. 程式人生 > >C++轉換函式和隱式類型別轉換

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