2014-11-21 68 views
2

據我所知,使用const&以及所有其他奇特的C++東西,正如我聽說Bjarne Stroustrup在視頻中所說的那樣,「幫助編譯器」。我明白如何儘可能地使用&(引用)可以幫助提高程序的效率,但有一點我不明白的是const_iterator如何提供幫助。假設我用如何使用const_iterator導致編譯更高效的程序?

#include <string> 
#include <iostream> 

int main() 
{ 
    const std::string s = "Vote for Pat Buchanan in 2016"; 
    for (std::string::const_iterator i1(s.cbegin()), i2(s.cend()); i1 != i2; ++i1) 
     std::cout << *i1 << std::endl; 

    return 0; 
} 

,而不是

#include <string> 
#include <iostream> 

int main() 
{ 
    const std::string s = "Vote for Pat Buchanan in 2016"; 
    for (std::string::iterator i1(s.begin()), i2(s.end()); i1 != i2; ++i1) 
     std::cout << *i1 << std::endl; 

    return 0; 
} 

都是有效的。前者如何更有效率?如何迭代遍歷字符串const_iterator的速度比使用常規iterator迭代字符串的速度更快?它們不是相同的數據結構嗎?爲什麼你需要單獨的數據結構來遍歷遍歷整個程序的容器,而不是遍歷一個非常量的容器?

舉例來說,如果我寫我自己的字符串類StringCool所使用節點

node 
{ 
    char c; 
    node * next, * previous; 
} 

來遍歷它,我不明白爲什麼我會需要別樣的節點,通過不斷迭代StringCool的實例。關於StringCool實例的常量版本唯一不同的是,該類將不允許書寫。我可以給它一個字段的節點

const char c; 
const node * next, * previous; 

但我不明白如何迭代通過這樣的節點的鏈接列表會更快。

Related question:在C++中創建類時,是否可以定義在聲明類的實例時會發生什麼const

+3

Stroustrup是否真的說'const_iterator'更有效率,還是你外推? – 2014-11-21 14:54:49

回答

8

const_iterator不存在使程序更快,它存在類型安全。如果你想允許代碼迭代你的容器,但你想確保它不會修改內容,你可以給代碼const_iterator s。

爲什麼您需要單獨的數據結構來遍歷整個程序中常量的容器,而不是迭代通過非常量的容器?

你不一定需要const_iterator只是遍歷一個容器,但有獨立的迭代器類型可以讓你表達你的意圖更好。如果您想迭代而不更改任何內容,則使用const_iterator可以明確表示該意圖。

如果我有int數組我能通過int*到要訪問它的功能,但如果我要確保功能不修改數組元素我會通過const int*來代替。如果我有一個const int數組,然後我必須const int*,因爲我不能得到一個非常量int*陣列沒有使用可疑(可能危險)演員。

您可以使用const_iterator(或其等價物)對const或非const對象執行非修改遍歷。您只能使用可變的iterator來遍歷非const對象,以防止您嘗試修改const容器的元素。

相關問題:當​​在C++中創建類時,是否可以定義當類的實例被聲明爲const時會發生什麼?

沒有,同樣的構造函數被調用該對象是否被聲明爲const與否,和構造過程中的*this類型總是非const。

+0

但是,再次,問題不在於類型安全性和不變性。 – 2014-11-21 14:59:06

+0

問題是關於'const_iterator',所以它是間接關於類型安全不變性的。 – 2014-11-21 15:01:32

0

因爲編譯器可以假設你不會修改它的內容,即不同地緩存它。例如,有時這意味着避免複製。

Related answer:是的,通過const的方法 - 類成員函數的重載限定符。

+0

我可能誤解了「定義會發生什麼」 - 請評論並告訴我是否屬於這種情況。 – 2014-11-21 14:58:28

+1

在大多數情況下,編譯器很難證明對象沒有改變,它只能證明對象沒有通過給定的迭代器改變。此外,它甚至可以通過使用const_cast的迭代器進行更改(除了對象最初定義爲const之外,它是合法的) – user396672 2014-11-21 15:09:17