1. 程式人生 > >C++ explicit關鍵字 詳解(用於建構函式)

C++ explicit關鍵字 詳解(用於建構函式)

在C++程式中很少有人去使用explicit關鍵字,不可否認,在平時的實踐中確實很少能用的上。再說C++的功能強大,往往一個問題可以利用好幾種C++特性去解決。但稍微留心一下就會發現現有的MFC庫或者C++標準庫中的相關類宣告中explicit出現的頻率是很高的。瞭解explicit關鍵字的功能及其使用對於我們閱讀使用庫是很有幫助的,而且在編寫自己的程式碼時也可以嘗試使用。既然C++語言提供這種特性,我想在有些時候這種特性將會非常有用。 按預設規定,只用傳一個引數的建構函式也定義了一個隱式轉換。舉個例子: (下面這個CExample沒有什麼實際的意義,主要是用來說明問題)
//Example.h
#pragma once
class CExample
{
public:
	CExample(void);
public:
	~CExample(void);
public:
	int m_iFirst;
	int m_iSecond;
public:
	CExample(int iFirst, int iSecond = 4);
};
//Example.cpp
#include "StdAfx.h"
#include "Example.h"
CExample::CExample(void)
	: m_iFirst(0)
{
}
CExample::~CExample(void)
{
}
CExample::CExample(int iFirst, int iSecond):m_iFirst(iFirst), m_iSecond(iSecond)
{
}
//TestExplicitKey.cpp
...//其它標頭檔案
#include "Example.h"
int _tmain(int argc, _TCHAR* argv[])
{
	CExample objOne; //呼叫沒有引數的建構函式
	CExample objTwo(12, 12); //呼叫有兩個引數的建構函式
	CExample objThree(12); //同上,可以傳一個引數是因為該建構函式的第二個引數有預設值
	CExample objFour = 12; //執行了隱式轉換,等價於CExample temp(12);objFour(temp);注意這個地方呼叫了
	//編譯器為我們提供的預設複製建構函式
	return 0;
}
如果在建構函式宣告中加入關鍵字explicit,如下 explicit CExample(int iFirst, int iSecond = 4); 那麼CExample objFour = 12; 這條語句將不能通過編譯。在vs05下的編譯錯誤提示如下 error C2440: 'initializing' : cannot convert from 'int' to 'CExample'         Constructor for class 'CExample' is declared 'explicit' 對於某些型別,這一情況非常理想。但在大部分情況中,隱式轉換卻容易導致錯誤(不是語法錯誤,編譯器不會報錯)。隱式轉換總是在我們沒有察覺的情況下悄悄發生,除非有心所為,隱式轉換常常是我們所不希望發生的。通過將建構函式宣告為explicit(顯式)的方式可以抑制隱式轉換。也就是說,explicit建構函式必須顯式呼叫。
引用一下Bjarne Stroustrup的例子:
class String{
      explicit String(int n);
      String(const char *p);
};
String s1 = 'a'; //錯誤:不能做隱式char->String轉換
String s2(10);   //可以:呼叫explicit String(int n);
String s3 = String(10);//可以:呼叫explicit String(int n);再呼叫預設的複製建構函式
String s4 = "Brian"; //可以:隱式轉換呼叫String(const char *p);再呼叫預設的複製建構函式
String s5("Fawlty"); //可以:正常呼叫String(const char *p);
void f(String);
String g()
{
    f(10); //錯誤:不能做隱式int->String轉換
    f("Arthur"); //可以:隱式轉換,等價於f(String("Arthur"));
    return 10; //同上
}
在實際程式碼中的東西可不像這種故意造出的例子。 發生隱式轉換,除非有心利用,隱式轉換常常帶來程式邏輯的錯誤,而且這種錯誤一旦發生是很難察覺的。 原則上應該在所有的建構函式前加explicit關鍵字,當你有心利用隱式轉換的時候再去解除explicit,這樣可以大大減少錯誤的發生。

相關推薦

C++ explicit關鍵字用於建構函式

C++ explicit關鍵字詳解(用於建構函式) C++提供了關鍵字explicit,可以阻止不應該允許的經過轉換建構函式進行的隱式轉換的發生。宣告為explicit的建構函式不能在隱式轉換中使用。 C++中,一個引數的建構函式(或者除了第一個引數外其餘引數都有預設值的多參建構函式),

C++ explicit關鍵字 用於建構函式

在C++程式中很少有人去使用explicit關鍵字,不可否認,在平時的實踐中確實很少能用的上。再說C++的功能強大,往往一個問題可以利用好幾種C++特性去解決。但稍微留心一下就會發現現有的MFC庫或者C++標準庫中的相關類宣告中explicit出現的頻率是很高的。瞭解e

C++ explicit關鍵字

首先, C++中的explicit關鍵字只能用於修飾只有一個引數的類建構函式, 它的作用是表明該建構函式是顯示的, 而非隱式的, 跟它相對應的另一個關鍵字是implicit, 意思是隱藏的,類建構函式預設情況下即宣告為implicit(隱式). 那麼顯示宣告的建構函式和隱式

C/C++ typedef用法真的很詳細

是p2++出錯了。這個問題再一次提醒我們:typedef和#define不同,它不是簡單的文字替換。上述程式碼中const pStr p2並不等於const char * p2。const pStr p2和const long x本質上沒有區別,都是對變數進行只讀限制,只不過此處變數p2的資料型別是我們自

Java中常用關鍵字不斷更新中

關鍵字1.static  在類中,用static關鍵字宣告的成員變數為靜態成員變數,或者叫做類屬性,類變數。    *它為該類的公共變數,屬於類,被該類的所有例項共享,在類被載入時被顯示初始化。    *對於該類的所有物件來說,static成員變數只有一份,被該類的所有物件共

c++學習第六篇拷貝建構函式

1.當函式的引數為類的物件時 #include<iostream> using namespace std; class CExample { private:     int a; public:     CExample(int b) &n

C# ListView用法

分組 創建 cti 排列 checkbox 定義 com 程序 erl 一、ListView類 1、常用的基本屬性: (1)FullRowSelect:設置是否行選擇模式。(默認為false) 提示:只有在Details視圖該屬性才有

C#漢字轉換拼音技術高性能

rim none pie 存在 asp pub net 如果 pinyin public static class ChineseToPinYin { private static readonly Dictionary<<span class=

C# partial 關鍵字

one sig 矛盾 att 效應 public 空間 clas 同一文件 我們新建一個Windows Form時,後臺代碼都會自動添加如下代碼: public partial class Form1 : Form { public Form1()

linux c/c++ GDB教程轉載

spec -h AS 不同的 argv 路徑 scheme execution ram 學習使用了GDB一段時間後,發現它真的好強大!好用! GDB是GNU開源組織發布的一個強大的UNIX下的程序調試工具。或許,各位比較喜歡那種圖形界面方式的,像VC、BCB等IDE的調試,

Python C API 使用

error 獲取 應該 tro pytho 都是 鍵值 字符 tin 簡介 介紹Python C API中的列表、元組、字典的使用,詳細的進行了API中方法的介紹。 Python List API List API 簡單介紹 int PyList_Check(PyObjec

C++ operator關鍵字

C++中的operator主要有兩個作用,一是操作符的過載,一是自定義物件型別的隱式轉換。 型別轉換操作符(type conversion operator)是一種特殊的類成員函式,它定義將類型別值轉變為其他型別值的轉換。 轉換操作符在類定義體內宣告,在保留字 operator 之後跟著轉換

Extreme Drift賽車遊戲C#源碼2

時間 blank 出現 進行 rest clam .text static cost Extreme Drift賽車遊戲C#源碼詳解(1) 接著上次的源碼分析: MainMenu場景的UGUI部分: Canvas中的EnoughMoney: 作用:當買車後金幣不足彈出的

C#委託使用Delegates

摘要 委託是C#程式設計一個非常重要的概念,也是一個難點。本文將系統詳細講解委託。   1. 委託是什麼? 其實,我一直思考如何講解委託,才能把委託說得更透徹。說實話,每個人都委託都有不同的見解,因為看問題的角度不同。個人認為,可以從以下2點來理解:  (1)

Java中Volatile關鍵字

一、基本概念 先補充一下概念:Java 記憶體模型中的可見性、原子性和有序性。 可見性:   可見性是一種複雜的屬性,因為可見性中的錯誤總是會違揹我們的直覺。通常,我們無法確保執行讀操作的執行緒能適時地看到其他執行緒寫入的值,有時甚至是根本不可能的事情。為了確保多個執行

extern "C"的使用

  extern "C"的主要作用就是為了能夠正確實現C++程式碼呼叫其他C語言程式碼。加上extern "C"後,會指示編譯器這部分程式碼按C語言的進行編譯,而不是C++的。由於C++支援函式過載,因此編譯器編譯函式的過程中會將函式的引數型別也加到編譯後的程式碼中,而不僅僅

C++之模板

C++模板   模板是C++支援引數化多型的工具,使用模板可以使使用者為類或者函式宣告一種一般模式,使得類中的某些資料成員或者成員函式的引數、返回值取得任意型別。   模板是一種對型別進行引數化的工具;   通常有兩種形式:函式模板和類模板;   函式模板針對僅引數型別不同的函式;   類模板針對僅資料成

C++之類模板

C++ 除了支援函式模板,還支援類模板(Class Template)。函式模板中定義的型別引數可以用在函式宣告和函式定義中,類模板中定義的型別引數可以用在類宣告和類實現中。類模板的目的同樣是將資料的型別引數化。 宣告類模板的語法為: template<typenam

c++實戰開發類與物件

一、面向物件程式設計介紹 (一)什麼是面向物件?      面向將系統看成通過互動作用來完成特定功能的物件的集合。每個物件用自己的方法來管理資料。也就是說只有物件內部的程式碼能夠操作物件內部的資料。

C語言中二維陣列名與陣列地址、首行地址、首行首元素地址關係與區別初學者必須掌握

C語言作為很多大學理工科都會學習的語言,作為一種程式設計入門語言。但是相對於其他高階程式語言來說相對是比較難,尤其是指針,不知道有多少莘莘學子都是因為它,從C語言入門到放棄。想當年,筆者在大一學習C語言