2013-03-09 93 views
0

在C++中,類構造函數可以使用初始化列表,我被告知這是一個性能特徵,它可以通過避免額外分配來提高性能。所以我想知道是否有類似的方法在C中實現相同的功能,這些功能基本上用於初始化C++類構造函數的結構。在C中的C++構造函數初始化列表替代?

我對C++編譯器中的特性如何工作有點不清楚,因此有關該主題的任何其他信息也將被讚賞。

+2

我很懷疑聲稱它是一個性能特徵。 – Joe 2013-03-09 17:05:49

+0

如果您想避免不必要的(重複)初始化,您可以使數據爲靜態。 – teppic 2013-03-09 17:12:18

+0

@Joe - IIRC聲稱是在LiveLessons的「C++基礎知識」中提出的,但可能是錯誤的,這當然是在我觀看的一些視頻教程中做出的。 – dtech 2013-03-09 17:14:30

回答

2

在C++構造函數中,初始化列表允許C++編譯器在成員變量的位置就地創建構造函數,而不是使用賦值運算符,複製構造函數或移動構造函數初始化成員變量。有關更多詳細信息,請參閱Section 10.6 of the C++ FAQ

在C中,C編譯器沒有提供這樣的自動操作。這意味着程序員直接控制所有初始化,並且不需要特殊語言功能來避免這些額外的操作。

爲了更加清楚一點,可以考慮當你使用分配在C初始化++構造會發生什麼:

  1. 成員變量先用臨時對象構造
  2. 默認構造函數
  3. 構建
  4. 調用賦值或移動賦值運算符以重新初始化臨時的成員變量。
  5. 在臨時調用析構函數。

雖然有些編譯器可以在某些情況下優化此功能,但是您的里程可能會有所不同,並且C++編譯器無法在所有情況下優化這些步驟。現在,考慮程序員如何在C中重複這些步驟:

void my_struct_init(struct my_struct* sp) 
{ 
    member_init_default(&sp->the_member); /* default constructor for member */ 

    struct member memb; /* temporary on stack */ 
    member_init_other(&memb, ...params...); /* initialize memb */ 
    member_assign(&sp->the_member,&memb); /* assign member */ 
    member_finalize(&memb);     /* finalize the temporary */ 
} 

很少有C程序員會這樣做(沒有很好的理由)。相反,他們會自動的代碼的優化:

member_init_other(&sp->the_member, ...params...); 

的功能用C++存在,因爲編譯器做了很多的東西自動爲程序員。這通常會讓程序員的生活更輕鬆,但需要初始化列表等功能來幫助編譯器生成最佳代碼。 C編譯器提供了一個更簡單的底層機器模型,自動執行更少的操作,因此需要更少的功能(儘管不一定需要更少的工作)來生成類似的最佳代碼。

4

C沒有任何相似的特性,但是因爲C也沒有構造函數,所以沒有不必要的賦值的危險。

更大的原則是,將一個特徵引入語言通常需要額外的特徵來加強原始特徵。一個微不足道的例子是線程。如果線程作爲一個功能被構建到語言中,那麼如何同步它們就成了一個直接的問題。因此同步也是需要的。所以你可以看到沒有內置線程或者同步和語言的語言(比如C),但是沒有其他語言。在這裏,構造函數是線程的,因爲同步是列出初始值設定項。

+0

我知道沒有這樣的功能,我只是問,如果性能優勢是適用的,並且可以在C中實現,就像大多數C++功能那樣缺少像多態性一樣,例如... – dtech 2013-03-09 17:13:01

+0

在C變量中只是空間記憶直到你分配給他們。在C++中,構造變量,並在聲明時使用空值(如果適用)。初始化程序允許您確保在分配所需值之前未分配空值。 – Will 2013-03-09 17:18:26

+0

是@威爾是對的,這正是我所說的。 C++中的構造函數是多個賦值的危險可能導致問題的地方。由於C沒有構造函數,所以沒有危險,所以不需要任何類似的初始化。作業陳述是你擁有和所有你需要的。 – Gene 2013-03-09 17:20:24

-1

你可以寫一個單獨的函數,並調用它,當你從一個類創建一個對象,然後把它傳遞給它:

C:

typedef struct { 
     int x; 
}mine; 

void mine_initializer(mine* me) 
{ 
     me->x = 4; //initialization 
} 

int main(void) 
{ 
     mine me; 
     mine_initializer(&me); 
     return 0; 
} 

你也可以這樣做,在C++:

struct mine{ 
     int x; 
     void initialize() 
     { 
       x = 4; //initialization 
     } 
}; 



void main(void) 
{ 
     mine me; 
     me.initialize(); 
     printf("%d",me.x); 
} 

這將輸出4作爲結果。

+0

不是我真正要求的,再加上你使用成員訪問'.'上的一個指針...... – dtech 2013-03-09 17:29:14

+0

@ddriver修正了它! oopsie!你想要一個自動初始化器嗎? – 2013-03-09 17:29:32

相關問題