C 中explicit關鍵字的使用

2021-09-23 23:35:45 字數 2905 閱讀 6103

看書看到了explicit關鍵字,就來做個筆記,講得比較明白,比較淺。

在c++中,我們有時可以將建構函式用作自動型別轉換函式。但這種自動特性並非總是合乎要求的,有時會導致意外的型別轉換,因此,c++新增了關鍵字explicit,用於關閉這種自動特性。即被explicit關鍵字修飾的類建構函式,不能進行自動地隱式型別轉換,只能顯式地進行型別轉換。

注意:只有乙個引數的建構函式,或者建構函式有n個引數,但有n-1個引數提供了預設值,這樣的情況才能進行型別轉換。

下面通過一段**演示具體應用(無explicit情形):

1 /* 示例**1 */

2 class demo

3 ;

上述四種建構函式:

建構函式1沒有引數,無法進行型別轉換!

建構函式2有乙個引數,可以進行型別轉換,如:demo test; test = 12.2;這樣的呼叫就相當於把12.2隱式轉換為demo型別。

建構函式3有兩個引數,且無預設值,故無法使用型別轉換!

建構函式4有3個引數,其中兩個引數有預設值,故可以進行隱式轉換,如:demo test;test = 10;  。

下面講述使用了關鍵字explicit的情況:

1  1 /* 示例**2 */

2 2 class demo

3 3 ;

在上述建構函式2中,由於使用了explicit關鍵字,則無法進行隱式轉換。即:demo test;test = 12.2;是無效的!但是我們可以進行顯示型別轉換,如:

demo test;

test = demo(12.2); 或者

test = (demo)12.2;

眾所周知,c++的基本型別中並非完全的對立,部分資料型別之間是可以進行隱式轉換的。

所謂隱式轉換,是指不需要使用者干預,編譯器私下進行的型別轉換行為。很多時候使用者可能都不知道進行了哪些轉換。

c++物件導向的多型特性,就是通過父類的型別實現對子類的封裝。

通過隱式轉換,你可以直接將乙個子類的物件使用父類的型別進行返回。

在比如,數值和布林型別的轉換,整數和浮點數的轉換等。

某些方面來說,隱式轉換給c++程式開發者帶來了不小的便捷。

c++是一門強型別語言,型別的檢查是非常嚴格的。

如果沒有型別的隱式轉換,這將給程式開發者帶來很多的不便。

當然,凡事都有兩面性,在你享受方便快捷的一面時,你不得不面對太過智慧型以至完全超出了你的控制。

風險就在不知不覺間出現。

#參考:

#以上四種情況下的隱式轉換,都滿足了乙個基本原則:低精度 –》 高精度轉換。

不滿足該原則,隱式轉換是不能發生的。

當然這個時候就可以使用與之相對於的顯式型別轉換(又稱強制型別轉換),使用方法如下:

double a = 2.0;

int b = (int)a;

使用強制型別轉換會導致精度的損失,因此使用時務必確保你已經擁有足夠的把握。

隱式轉換的風險一般存在於自定義的類建構函式中。

按照預設規定,只有乙個引數的建構函式也定義了乙個隱式轉換,將該建構函式對應資料型別的資料轉換為該類物件。

既然隱式轉換存在這麼多的風險,那如何能夠禁止隱式轉換的發生呢。

c++中提供了explicit關鍵字,在建構函式宣告的時候加上explicit關鍵字,能夠禁止隱式轉換。使用方法如下: 1

2345

6classtest

加上該關鍵字以後,如下的操作是合法的: 1

test(10);

如下的操作就變成非法的了: 1

test aa = 10;

這樣就可以有效的防止隱式轉換的發生,從而能夠對程式進行精確控制,達到提高品質的目的。

《c++ primer》中提到:

「可以用 單個形參來呼叫 的建構函式定義了從 形參型別 到 該類型別 的乙個隱式轉換。」

這裡應該注意的是, 「可以用單個形參進行呼叫」 並不是指建構函式只能有乙個形參,而是它可以有多個形參,但那些形參都是有預設實參的。

那麼,什麼是「隱式轉換」呢? 上面這句話也說了,是從 建構函式形參型別 到 該類型別 的乙個編譯器的自動轉換。

下面通過**來看一看:

#include "stdafx.h"

#include #include using namespace std ;

class book //定義了乙個書類

//類的建構函式,即那個「能夠用乙個引數進行呼叫的建構函式」(雖然它有兩個形參,但其中乙個有預設實參,只用乙個引數也能進行呼叫)

現在使用者只能進行顯示型別轉換,顯式地建立臨時物件。

總結一下:

可以使用乙個實參進行呼叫,不是指建構函式只能有乙個形參。隱式類型別轉換容易引起錯誤,除非你有明確理由使用隱式類型別轉換,否則,將可以用乙個實參進行呼叫的建構函式都宣告為explicit。explicit只能用於類內部建構函式的宣告。它雖然能避免隱式型別轉換帶來的問題,但需要使用者能夠顯式建立臨時物件(對使用者提出了要求)。

c 中explicit關鍵字

c 中的explicit關鍵字用來修飾類的建構函式,表明該建構函式是顯式的。既然有 顯式 那麼必然就有 隱式 那麼什麼是顯示而什麼又是隱式的呢?按照預設規定,只有乙個引數的建構函式也定義了乙個隱式轉換,將該建構函式對應資料型別的資料轉換為該類物件,如下面所示 include using namesp...

c 中的explicit關鍵字

c 中的explicit關鍵字 c 中的explicit關鍵字用來修飾類的建構函式,表明該建構函式是顯式的,既然有 顯式 那麼必然就有 隱式 那麼什麼是顯示而什麼又是隱式的呢?如果c 類的建構函式有乙個引數,那麼在編譯的時候就會有乙個預設的轉換操作 將該建構函式對應資料型別的資料轉換為該類物件,如下...

c 中的explicit關鍵字

c 中的explicit關鍵字用來修飾類的建構函式,表明該建構函式是顯式的,既然有 顯式 那麼必然就有 隱式 那麼什麼是顯示而什麼又是隱式的呢?如果c 類的建構函式有乙個引數,那麼在編譯的時候就會有乙個預設的轉換操作 將該建構函式對應資料型別的資料轉換為該類物件,如下面所示 class myclas...