2011-07-04 52 views
12

這是關於在C++中使用構造函數的非常簡單的問題。我將以採訪對話的形式呈現(很難以任何其他形式呈現)在C++中使用構造函數

採訪者 -什麼是構造函數?
me -構造函數是特殊函數,它確保所有對象在使用前都被初始化。

訪問者 -什麼是初始值列表?
me -這是一個所有初始化發生的列表。只有在初始化所有數據成員之後才輸入構造函數的主體,或者調用所有成員對象的某個構造函數。

面試官 -這意味着初始化是在初始化器列表中執行的,而不是在構造器內部執行的。但你說構造函數初始化對象!你不是嗎?你想回答我的第一個問題嗎?
me -我認爲構造函數不會賦值,它會在已經初始化的成員對象上調用賦值運算符。

所以我想問你可以

初始化列表是如何工作的

函數的起始地址是什麼之間&起始括號[{]?

或只是回答我如何說服我的面試官。

+3

「什麼是初始化列表?」一個用詞不當。你在談論'ctor-initializer'。初始化器列表完全是其他東西。 –

+1

@Amar - 'int a [] = {1,2,3,4,5};' - '{1,2,3,4,5}'是初始化列表。 – Mahesh

+0

我的意思是構造函數初始化列表; like sample :: sample:A(a)() – Amar

回答

3

你超越了它,允許面試官混淆你。

初始化對象的成員是不是與初始化對象本身一樣。僅僅因爲成員具有理智的價值觀並不意味着這個對象已經被構建。在構造函數完成之前,對象本身尚未正確初始化。

+0

接受這個答案的理由是,你的回答「僅僅因爲成員具有理智的價值觀並不意味着對象已經被構建」提醒我,只有在完成以下事情之後才能構建對象 - 1)默認ctot &CCtor&分配操作員被提供,如果不是由班級作家提供的 2)虛擬指針和虛擬表格設置正確 3)資源分配,如果有一些指針 – Amar

+0

順便說一句,這不是一個真實的採訪情景,一種方式:) – Amar

7

從技術上講,你的解釋是準確的。沒有成員可以從ctor機構內部初始化;只在ctor-initializerctor正文中的任何成員訪問權限只能分配。

在輸入ctor正文之前,所有成員都被「初始化」。

然而,說起來更廣泛地說,因爲身體始終遵循的初始化,它說,作爲—一旦—構造已結束對象初始化一個單元......包括身體。

部分原因是,從廣義上講,您可能會考慮初始化以包含您必須在您的ctor正文中執行的業務邏輯,儘管這與實際初始化數據成員不同。

+0

這裏的初始化究竟意味着什麼?例如:'struct X {int a,b; X(int c):a(c){b = c + 1;}',什麼時候被初始化? –

+2

@logic:'b'在大括號之前被*初始化*。之後,這只是一種調整。 – Xeo

+0

@Xeo感謝您的清除。 –

1

有關初始化列表的主要內容是效率和代碼可讀性。

可讀性部分是不言自明的,因爲您知道在哪裏查看值的初始化位置。節約效率是因爲如果你在構造函數的代碼中爲它們賦值,那麼它們將被賦值兩次:首先當對象被創建時,它們將被分配由該數據類型的默認構造函數提供的值,然後它們將在你的對象的構造函數中被分配一個新的值。初始化列表只是確保它們以您指定的值初始化。

例如,下面是我在一個雙向鏈表實現所使用的初始化列表的例子:

template <typename T> 
LinkedList<T>::LinkedList() 
: size(0) 
, pHead(NULL) 
, pTail(NULL) 
{ 
} 

儘管效率較低的版本,其中大小,PHEAD和PTAIL得到分配如下兩次:

template <typename T> 
LinkedList<T>::LinkedList() 
{ 
    size = 0; 
    pHead = NULL; 
    pTail = NULL; 
} 
0

初始值設定項列表是構造函數的一部分。每個構造函數都有自己的。

1

本質上,你是正確的,但不應將成員初始值設定項視爲與構造函數分開。初始化程序是構造函數的一部分,並在構造函數的主體之前調用。

當您聲明內置類型的自動變量時,它既是定義也是聲明。這是一個聲明,因爲標識符綁定到一個類型,並且它是一個定義,因爲編譯器爲它分配存儲空間。

int var1; // declares/defines var of type int 

int var2 = 0; // declares/defines a var of type int and initializes it to 0 

初始化程序在定義初始值時設置初始值,但在初始化程序之前已經定義初始值。

int x = 5; 
int y = 5; 

int main() 
{ 
    int x = x; // x is undefined here not 5 because x refers to itself 
    int y[y]; 
    int size = sizeof(y)/sizeof(int); // size is 5 (y[5]) since y isn't defined until after the enclosing bracket so y referred to the global y in the declaration. 
} 

有一些變量必須然而初始化。常量和參考。

這與構造函數相同。成員的定義就在委員會主體之前。這是調用構造函數時成員和基礎的定義順序。

  1. 虛基類
  2. 基類
  3. 部件 - 在它們被宣佈
  4. 構造函數體執行

離開構造體後的順序,一切都已初始化。

如果你不使用初始值設定項,那麼你可以假定它已經在進入ctor體時已經定義了,但是你不能認爲它有任何特定的值。同樣,常量和引用必須在成員初始化程序中初始化。