程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> c++類的隱式轉換與強迫轉換重載詳解

c++類的隱式轉換與強迫轉換重載詳解

編輯:關於C++

c++類的隱式轉換與強迫轉換重載詳解。本站提示廣大學習愛好者:(c++類的隱式轉換與強迫轉換重載詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是c++類的隱式轉換與強迫轉換重載詳解正文


在寫這篇文章之前,讓我們先回想一下編譯器經由過程婚配進程肯定挪用哪個函數的婚配次序:
(1)尋覓和應用最相符函數名和參數類型(包含前往值)的函數,若找到則挪用;

(2)不然,尋覓一個函數模板,將其實例化發生一個婚配的重載函數,若找到則挪用;

(3)不然,尋覓可以經由過程類型轉換停止參數婚配的重載函數,若找到則挪用它。

假如以上步調均未找到婚配函數,則這個挪用是毛病的;假如這個挪用有多於一個的婚配選譯,則挪用婚配湧現二義性,也是毛病的。
 
類型轉換是將一品種型的值映照為另外一品種型的值。類型轉換現實上包括有主動隱含和強迫的兩種。

C說話編譯體系供給的外部數據類型的主動隱式轉換規矩以下:

1.法式在履行算術運算時,低類型可以轉換為高類型。

2.在賦值表達式中,左邊表達式的值主動隱式轉換為右邊變量的類型,並賦值給它。

3.當在函數挪用時,將實參值賦給形參,體系隱式地將實參轉換為形參的類型後,賦給形參。

4.函數有前往值時,體系將主動地將前往表達式類型轉換為函數類型後,賦值給挪用函數。

在以下情況下,體系會停止隱式轉換的。當在法式中發明兩個數據類型不相容時,又不克不及主動完成隱式轉換,則將湧現編譯毛病。例如:
   int* p = 100;
在這類情形下,編譯法式將報錯,為了清除毛病,可以停止以下所示的強迫類型轉換:
   int* p = (int *)100;
將整型數100顯式地轉換成指針類型。

結構函數具有類型轉換功效

在現實運用中,當類界說中供給了單個參數的結構函數時,該類便供給了一種將其他數據類型的數值或變量轉換為用戶所界說數據類型的辦法。是以,可以說單個參數的結構函數供給了數據轉換的功效。上面經由過程一個例子進一步解釋單參數結構函數的類型轉換功效。

#include
classA
{
public:
A(){ m=0; }
A(doublei) { m=i; }
voidprint() { cout<<M<
private:
doublem;
};

voidmain()
{
Aa(5);
a=10; //a與10是分歧的數據類型
a.print();
}

法式的輸入成果為:
  10
在該法式中,賦值語句a=10;中,賦值號雙方數值10和對象a是兩上不相容的數據類型,可是它卻能順遂經由過程編譯法式,而且輸入顯示准確成果,其重要緣由是得益於單參數的結構函數。編譯體系選經由過程尺度數據類型轉換,將整型數值10轉換成double型,然後,再經由過程類中界說的單參數結構函數將double型數值轉換為A類類型,最初把它賦值給a。這些轉換都是主動隱式完成的。

關於下面的法式,彌補一點:
Aa = 10;

Aa;
a= 10;
二者是分歧的,前者對a停止初使化,編譯器會測驗考試將10隱式轉換為A類型,如許將惹起a的A(doublei)結構函數直接被挪用。
後者屬於賦值語句,編譯器將樹立一個暫時對象,並將10隱式轉換為A類型。假如我們顯示挪用
(A)10;
這也將樹立一個暫時對象,惹起A的結構函數被挪用。

還有一點要留意,編譯器只會停止一次隱式轉換(C時辰庫的內置類型如intshort char等)除外,上面的語句解釋了這點:
m_rst->GetFields()->GetItem(nCol)->Value= (_bstr_t)sValue;
下面Value是COM的變體類型,“Value=”將惹起operator= (_bstr_t)被挪用。假如下面省略(_bstr_t),編譯器將產生毛病,由於沒有operator= (char*)如許的重載,編譯器不會為我們停止兩次以上的隱式轉換。

在函數挪用進程中,運算符重載和結構也是一個函數挪用,假如婚配的函數如無二義性,那末將可以發生一次隱式轉換。假如上句的Value變體類只要一個operate= (_bstr_t),那末既使如許寫->Value= sValue; 編譯器也會試圖將sValue隱式轉換為_bstr_t類型。

還有一種情形

classA
{
inta;
public:
A(){ };
A(int_a) { a = _a; };
Operatorint() { return a; }
}

有以下挪用:

Aa(10);
Aa2 = (int)(int)a;   //只相當於Aa2 = (int)a; 由於第一個就近曾經轉成了int,第二//個就不消再轉了

比擬成心思吧,A類既有將int隱式轉換A的結構,也有int()轉換函數供強迫轉換,(int)(int)a將以就近准繩的方法停止。假如就近轉換掉敗,編譯器將報錯。好比:

classB
{
};
Aa2 = (B)a;

Aa2 = (B)10;

編譯器報如許的毛病:"errorC2440: “類型轉換”:沒法從“int”轉換為“B”"
可知,我們本身編寫的結構和轉換函數何等主要。

轉換函數
轉換函數又稱類型強迫轉換成員函數,它是類中的一個非靜態成員函數。它的界說格局以下:

   class<類型解釋符1>
    {
     public:
      operator<類型解釋符2>();
      …
    }

這個轉換函數界說了由<類型解釋符1>到<類型解釋符2>之間的映照關系。可見,轉換函數是用來將一品種型的數據轉換成為另外一品種型。上面經由過程一個例子解釋轉換函數的功效。

#include

classRational
{
public:
Rational(intd, int n)
{
den= d;
num= n;
}
operatordouble();//類型轉換函數
private:
intden, num;
};

Rational::operatordouble()
{
returndouble(den)/double(num);
}

voidmain()
{
Rationalr(5, 8);
doubled = 4.7;
d+= r;  //這句將挪用隱式轉換,相當於d= (double)r;
cout<<d<<ENDL;
}

法式輸入成果:
5.325

由法式可知,d是一個double型數值,r是Rational類的對象,這兩個分歧類型的數據停止加法之所以可以或許停止是得益於轉換函數operatordouble()。為使上述加法可以或許停止,編譯體系先檢討類Rational的解釋,看能否存在鄙人轉換函數可以或許將Rational類型的操作數轉換為double類型的操作數。因為Rational類中解釋了轉換函數operatordouble(),它可以在法式運轉時停止上述類型轉換,是以,該法式中完成了d=r;的操作。

界說轉換函數時應留意以下幾點:
(1)轉換函數是用戶界說的成員函數,但它如果非靜態的。
(2)轉換函數的弗成以有前往值。(意思是聲明中弗成以有前往值)
(3)轉換函數也不帶任何參數。
(4)轉換函數函數還不克不及界說為友元函數。

轉換函數的稱號是類型轉換的目的類型,是以,不用再為它指定前往值類型;轉換函數是被用於本類型的數值或變量轉換為其他的類型,也不用帶參數。

類中的結構函數完成其他類型到類類型的轉換,而重載強迫轉換完成類類型到其他類型的轉換。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved