1. 程式人生 > >C++悄悄做的那些事

C++悄悄做的那些事

摘自:《編寫高質量程式碼:改善c++程式的150個建議》

所有類都一個類似的中樞骨幹,人送外號“Big Three”:

一個或多個建構函式  +  一個解構函式  +  一個拷貝複製運算

它們控制著類的基本操作:新物件的建立和初始化,為物件賦一新值,以及類的消亡清理。難道就沒有一個類超出“三界”,打破這一規律?

答案是肯定的,在類的世界裡,沒有例外。即使像下面完成一個空類的定義:

Class CEmpty{};

雖然你沒有自己宣告Big Three,但是編譯器 會悄悄的為你宣告一個 它自己的版本。所以 你寫下空類CEmpty的定義時,其 本質和下面的 程式碼 是一樣的 :

Class CEmpty
{
    public:
           CEmpty();
           CEmpty(const CEmpty &);
           ~CEmpty();
           CEmpty& operator = (const CEmpty& other);
 };
這是多麼的奇妙,同時又是多麼的可怕啊!,C++編譯器竟然做了那麼多事,不過這些函式只有在它們被需要的時候才會生成。如下示:
void Function()
{
    CEmpty e1;     // default constructor
    CEmpty e2(e1); // copy constructor
    e2 = e1;       // copy assignment operator
}
當然在Function 結束的時候,會默默呼叫~CEmpty(),釋放兩個區域性物件。

需要注意的是

   編譯器的copy constructor 和 copy assignment operator,只是簡單地將原物件的每一個Non-static資料成員拷貝到目標物件中,簡單粗暴,因而容易 出現問題。

  在C++11中,標準引入兩個指示符delete 和 default,以便讓程式設計師自行決定是否需要編譯器自動的生成這些函式。delete告訴編譯器不自動產生這個函式。default告訴編譯器產生一個預設的函式。如一下程式碼:

// C++ 11 only
class A
{
    A() = default;                                     // need generate
    virtual ~A() = default;                        // need generate
    A& operator = (const A&) = delete;   // forbitten generate
    A( const A&) = delete;                      // forbitten generate
}
除了新增“主幹”函式,對於空類CEmpty,C++編譯器還多做了一件事:為空類隱含的加一個位元組。按照一般邏輯,CEmpty類中不包含任何資料,是名副其實的空類,所以它的大小應該是 0;貌似理由很充足,事實請參看下面程式碼:
#include <iostream>
using namespace std;
int main()
{
    cout<<"sizeof(CEmpty) = "<< sizeof(CEmpty)<<endl;
    return 0;
}
程式在32位系統中的輸入結果如下:

sizeof(CEmpty) = 1

這是為什麼呢 ?

空類大小不為0的原因還需從例項化角度進行分析。所謂例項化就是在記憶體中分配一個具體的物件,沒一個物件都必須在記憶體中有一個獨一無二的地址,當然空類也不例外。為了達到這個目的,編譯器會悄悄給空類隱含的新增一個位元組,這樣在例項化的時候就能分配到獨一無二的地址了。

相關推薦

C++悄悄那些

摘自:《編寫高質量程式碼:改善c++程式的150個建議》 所有類都一個類似的中樞骨幹,人送外號“Big Three”: 一個或多個建構函式  +  一個解構函式  +  一個拷貝複製運算 它們控制著類的基本操作:新物件的建立和初始化,為物件賦一新值,以及類的消亡清理。難道就

C語言的那些--二維陣列作為實參傳參

#include <stdio.h> #include <stdint.h> void fun(uint8_t (*buf)[4],uint8_t line,uint8_t r

C# 6.0那些

這兩天期中考試沒時間去看Connect();直播,挺可惜的,考完後補看了Connect(); 把C#6.0的新東西總結一下。 自動屬性初始化 (Initializers for auto-properties) 以前我們是這麼寫的 為一個預設值加一個後臺欄位

一文搞懂C/C++中指標那些(上篇)

一 指標變數 1.間接存取        指標變數的值為地址;普通變數的值為資料;其中“*”為指標運算子。&是地址操作符,用來引用一個記憶體地址。通過在變數名字前使用&操作符,我們可以得到該變數的記憶體地址。        針對記憶體資料的

C++ STL】細數C++ STL 的那些---vector (動態陣列)

一,vector概述         vector是一個順序容器,可以存放各種型別的物件,簡單地說,vector是一個能夠存放任意型別的動態陣列,能夠增加和壓縮資料。         vector是動態空間,隨著元素的增加內部機制可以自行擴充空間,而array則是固定大小空

C++】引用那些(2)

一、傳值、傳引用效率比較 以值作為引數或者返回值型別,在傳參和返回期間,函式不會直接傳遞實參或者將變數本身直接返回,而是傳遞實 參或者返回變數的一份臨時的拷貝,因此用值作為引數或者返回值型別,效率是非常低下的,尤其是當引數或者返 回值型別非常大時,效率就更低。 #include <ti

C++】引用那些(1)

一、什麼是引用?  引用不是新定義一個變數,而是給已存在變數取了一個別名,編譯器不會為引用變數開闢記憶體空間,它和它 引用的變數共用同一塊記憶體空間。 比如:李逵,在家稱為"鐵牛",江湖上人稱"黑旋風"。 型別& 引用變數名(物件名) = 引用實體; void

C++互動的那些

一、檢視.so檔案crash的堆疊資訊 授予超級使用者許可權 2.進入到/data/tombstones目錄 3.列出tombstones目錄下的檔案及修改時間 4.將離Cras

C++ STL】細數C++ STL 的那些 -- stack(棧)

           1)Stack是一種關聯容器,是通過簡單地修飾線性類deque的介面而獲得的另一種“容器類”,往往被歸結為配接器(adapter)而不是容器(container)。                  stack不能遍歷,所以沒有迭代器!!!      

c++ Template 的那些

1.模板的概念。 我們已經學過過載(Overloading),對過載函式而言,C++的檢查機制能通過函式引數的不同及所屬類的不同。正確的呼叫過載函式。例如,為求兩個數的最大值,我們定義MAX()函式需要對不同的資料型別分別定義不同過載(Overload)版本。 //函式1. int max(int x,i

C#(或者說.NET/Mono)能那些

不做語言之爭,只陳述事實: 1、桌面軟體 不僅是在Windows上,有了開源的Mono,在Apple Mac和Linux(如:Ubuntu)上也有C#的施展天地。並且還可以通過mkbundle工具讓C#程式脫離Mono框架在Mac/Linux上執行,就像直接用C/C++編譯的程式。

Android Studio 那些|Activity文件前標識圖標顯示為 j 而是 c

div roi 右下角 ext blog 識圖 cti 問題: content 問題:Activity文件前標識圖標顯示為 j 而是 c 的圖標,或是沒有顯示,並且自己主動提示不提示 解決:這是由於你的studio設置了省電模式,你能夠通過 File>

IPv4中的A,B,C類網及子網掩碼那些

來看 了解 擁有 nbsp 開發 信息 alt 位或 其余 IP 地址的主要類型有五種 A B C D 和 E 一般 A B C 類地址更為常用 每類地址都是由 32 位或 4 個字節組成 A類地址: 在 A 類地址中第一個 8 位字節表示網絡部分 其余 3 個 8 位字節

C專家編程》---不知道的那些

解決 inter pan 無反應 編程 get 符號 print 說明 1.char *b = const char *a 會報警告,而const char* a = char *b不會,要使這種賦值形式合法,必須滿足下列條件之一:   1)兩個操作數都是指向有限定符或無限

C++的那些 1

最近在看c++的一些庫檔案,裡面的一些比較陌生但看起來挺有用的一些東西,在此記下,以免日後看到再翻找資料。 template <size_t _Nb> 這是在看bitset的時候看到的,之前用bitset的時候也沒太留意,這是才發現bitset的類模板引數不是一個型別,而是一個數,這才發現原來

C++和遊戲開發那些,告訴你怎麼用C++縱橫遊戲程式設計!

C語言和C++ C 語言可以說是一門設計的非常成功的語言。但是C語言沒有OOP的特性,在做一些大型專案的時候力不從心。一些大型的C專案,隨著專案的臃腫,人類基本沒辦 法維護這個專案了。要維護這麼龐大的專案而又不出錯,只能加入一些OOP特性重構,有經驗的C程式設計師寫著寫著,很多概念就類似C+

你的月亮我的C(六):指標和陣列的那些

先來看幾個問題,一邊從問題中入手,一邊看看指標和陣列之間的那些事: 1、char arr[ ]和char *arr是等價的嗎? 答:不是。看下指標和陣列的定義:陣列是一個用同一型別的多個連續元素組成的事先分配好的記憶體塊。指標是一個可以對任何資料元素的引用。所以陣列的定義

ASP.NET C# JSON 格式轉換 « 關於網路那些...

ASP.NET JSON 格式轉換 首先透過 NuGet 封裝管理員來新增套件 在專案> 右鍵 > 管理 NuGet 套件... 在 瀏覽

ASP.NET C# 不同瀏覽器在 buffer 緩衝區 與Response.Flush() 表現差異比較 « 關於網路那些...

ASP.NET C# 不同瀏覽器在 buffer 緩衝區 與Response.Flush() 表現差異比較 ASP 輸出內容到網頁的方式基本上有兩種 直接輸出 緩

C# Thread 執行緒 « 關於網路那些...

C# Thread 執行緒 程式都會有一個主處理序 例如,在同一個主處理序,可能同時會需要送出多筆訂單、讀取大型檔案等專案要排隊 在這主要的處理序,可以額外建立