C 中的隱式轉換

2021-08-24 20:38:38 字數 1886 閱讀 1450

首先我們看下一種比較常見的技術——類建構函式的隱式轉換。這兒先說明下,之後的例子中,我會為了盡量突出主要內容,而忽略一些可以作為充分條件但非必要條件的東西,故設計的一些**存在「不完善」的嫌疑。因為為了堵住所有漏洞,往往會讓整個**讓人感覺其重心並非在我想介紹的技術上,而在「苦行僧」式的程式設計原則上。

我們知道c++是乙個型別嚴格的語言,比如下面乙個函式

void test_int_proxy(const int_proxy& v)

呼叫者對其傳參也應該是乙個int_proxy的物件,但是實際情況並非如此。那該如何表述,我個人覺得應該是:編譯器對其傳參應該是乙個int_proxy物件。這兩種表述的區別就是「呼叫者」和「編譯器」的區別。我們來看乙個實際例子,我們先假定int_proxy類這麼定義:

class int_proxy ;

public:

int value() const

private:

int _m;

};

該類非常簡單,它有乙個帶引數的建構函式,並使用引數列表形式初始化類的成員變數。

一般情況下我們都會這麼呼叫test_int_proxy方法:

test_int_proxy(int_proxy(100));
這種寫法我想沒人會有異議,但是如果出現下面這種寫法,就可能讓人感覺不可接受了:

test_int_proxy(100);
然而,這種寫法對上述類的定義來說是合法的!其效果和使用int_proxy控制住是一樣的。這是為什麼呢?這便是類建構函式的隱式轉換技術。c++編譯器認為test_int_proxy方法傳入的應該是乙個const型別的int_proxy物件,然而如果它發現引數不是該物件時,就會使用該類中可以使用該引數進行構造物件的方法構造出乙個臨時的物件。我們例子中傳參100是個int型資料,而int_proxy正好有乙個攜帶int引數的建構函式。稍微總結下類建構函式隱式轉換的必要條件:

找不到傳參型別嚴格對應的函式

找到傳參型別嚴格匹配的類的建構函式

因為隱式轉換構造出的是臨時物件,所以不可修改,故觸發隱式轉換的函式的傳參型別必須要使用const修飾

但是個人覺得這種「奇巧淫技」還是不用為好。比如我們**中還有如下函式:

void test_int_proxy(const int& v)

那麼c++編譯器會針對傳100的呼叫上面這個過程。這樣乙個函式呼叫有兩個匹配的呼叫方法就會產生不確定性——這兒指的不確定性並非是指編譯器呼叫哪個方法的不確定性,而是指維護這段**的人對上述**做調整時容易忽略一些問題而導致的「人禍」。

再比如,我們在**中加入下面類和方法

class int_proxy_2 ;

public:

int value() const

private:

int _m;

};

void test_int_proxy(const int_proxy_2& v)

那麼編譯器不能確定隱式轉換是要轉換哪個類,更不知道是呼叫哪個test_int_proxy方法了。

限制類建構函式的隱式轉換的方法也很簡單,就是給對應的建構函式加上explict關鍵字

class int_proxy ;

這樣通過隱式轉換而構造臨時物件的圖謀將會被察覺並禁止。

mysql 隱式轉換 mysql中的隱式轉換

在mysql查詢中,當查詢條件左右兩側型別不匹配的時候會發生隱式轉換,可能導致查詢無法使用索引。下面分析兩種隱式轉換的情況 看表結構 phone為 int型別,name為 varchar 兩種情況都可以用到索引,這次等號右側是 2 注意帶單引號喲,左側的索引欄位是int型別,因此也會發生隱式轉換,但...

c 中的隱式型別轉換

型別轉換,分為隱式型別轉換和顯示型別轉化。這裡主要討論含無符號性的隱式型別轉化。賦值操作 示例 unsigned char c 1 c的結果是255。算術表示式 算術表示式中,含有整型與無符號型,int性會自動轉化為無符號型。示例 unsigned u 10 int i 42 cout u i 以下...

c 隱式轉換

class string string s1 a 錯誤 不能做隱式char string轉換 string s2 10 可以 呼叫explicit string int n string s3 string 10 可以 呼叫explicit string int n 再呼叫預設的複製建構函式 str...