2011-09-24 67 views
0

我真的不明白我在下面做錯了什麼。我有一個名爲Settings的類,其結構如下所示,以及下面列出的兩個函數。我遇到的問題是在重載函數中重載const運算符[]時,將const修飾符放在哪裏。我需要在某處使用const_cast嗎?我錯過了什麼?重載const操作符時使用const_iterator []

class Settings 
{ 
    map<string, string> settingsMap; 
    map<string, string>::const_iterator itc; 

    const string getValue(string) const; 

    public: 
    const string operator[](string) const; 
}; 

const string Settings::operator[](string K) const 
{ 
    return getValue(K); 
} 


const string Settings::getValue(const string K) const 
{ 
    const map<string, string> m = settingsMap; 
    itc = m.begin(); 
    while(itc != m.end()) 
    { 
     if(itc->first==K) 
      return itc->second; 
     itc++; 
    } 
    return 0; 
} 

在此先感謝。

+0

如果還有什麼需要知道解決這個問題,請告訴我。這只是我寫的一些練習代碼,希望能夠在C++中取得更好的效果。 – user962472

+0

由於您按值返回字符串,因此沒有必要返回const字符串。返回引用時,您需要const。聲明整個函數爲const就夠了。 –

+0

我喜歡Google C++風格指南的建議:不要因爲const而發瘋。類似於const int * const * const x;即使它準確地描述了const x是如何的,它可能是過度的。 –

回答

0

你的問題是不是與常量而是引用。
此外,您的類中的聲明必須完全匹配您在定義函數時使用的定義。

class Settings 
{ 
    map<string, string> settingsMap; 
    map<string, string>::const_iterator itc; 

    const& string getValue(const string& K) const; 
       //   ^^^^^ Added const to match definition below. 
       //     Also note the reference. This means you are referring 
       //     to the original value but because the reference is const 
       //     it cant be modified via this reference. 

// ^^^^^^ This const means the returned value is const. 
//   unless you return a reference this is meaningless. 
//   So also note the reference here are well. 

           //   ^^^^^^ The last const means the method will 
           //     NOT change the state of any members. 

    public: 
    const string& operator[](const string&) const; 
// ^^^^^^^^^^^^^ As above return a const reference. 
          // ^^^^^ As above pass parameters by const reference 
          //  otherwise it makes a copy of the parameter. 
             //  ^^^^^ function will not change any members. 
}; 

const string& Settings::operator[](const string& K) const // Must match above definition. 
{ 
    return getValue(K); 
} 


const string& Settings::getValue(const string& K) const 
{ 
    const map<string, string> m = settingsMap; 
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ As this is an object (not a reference) 
//        You are making a copy of the object into a local variable. 
//        This is probably not what you want. 

    const map<string, string>& m = settingsMap; // This works. 

    itc = m.begin(); 


    while(itc != m.end()) 
    { 
     if(itc->first==K) 
      return itc->second; 
     itc++; 
    } 

    return 0; 
// ^^^^^^^^ This is not a good idea. 
//   It is creating a string from a NULL pointer (0 is convertible to pointer). 
//   What you really wanted to do is return a string. This is also why your 
//   return type was not working as you expected. 

    static const string emptyResult; // create a static object to use as the empty result 
    return emptyResult; 
} 
0

如果函數getValue()修改成員itc,那麼它不能是const(除非它是可變的)。我建議你在函數的getValue()聲明ITC:

... 
const map<string, string> m = settingsMap; 
imap<string, string>::const_iterator itc = m.begin(); 
... 
+0

我會盡力回覆你。謝謝! – user962472

0

在c操作符[] ++有兩個含義:
(1)a[i] = x; //store x into a in position i
(2)x = a[i]; //load a in position i to x

第一個必須改變結構...因此結構不能爲const,所以你應該刪除最後一個const爲:const string operator[](const string); [注意這裏的參數是const string而不是string,因爲它可能不應該改變。另外,由於輸出字符串不應該被改變,所以它也應該被定義爲const

第二屆一個,也許應該返回string,而不是const string,所以你可能應該放棄第一conststring operator[](const string) const; [因爲這個運算的原結構沒有改變,最後const是好的,應該保持] 。另外請注意,參數是const string而不是string,因爲您不想鎖定參數。

你的情況:看來你要爲operator[]第二個含義,因此,你應該把它聲明:string operator[](const string) const;

+0

這是我正在尋找的第二個意義。在我目前的代碼中,我也有第一個代碼,但是當我得到這個代碼的時候,我把它剪掉了。我會嘗試你告訴我的並回復你。謝謝! – user962472

+0

@ user962472:np,請注意,您可能需要將'getValue()'更改爲'string getValue(const string K)const' [返回值可能應該是'string'而不是'const string']。 – amit

0

在你的宣言:

const string operator[](string K) const; 
如果你只想讀(及複印件)地圖的內容

,那麼正確的聲明應該是:

const string operator[](const string &k) const; 

返回類型應該是const,否則你可能會修改一個臨時值,這是不正確的。該參數可以通過const引用傳遞,因爲你沒有修改它。這一聲明,下面的代碼兩行會給你一個錯誤:

... 
s["abc"] = "cde"; // cannot modify, the return type is const 
s["abc"] += "efg"; // cannot modify, the return type is const 

原型聲明後,常量只是告訴你,operator[]不 修改對象,所以它裏面的代碼做方法operator[]和 與其用法無關。由於這個原因,const_iterator應該被定義爲operator[]代碼中的局部變量。

返回類型的const避免了修改臨時值(返回類型)的可能性。爲了提高效率,您可以通過返回一個const引用來獲得相同的結果。

const string& operator[](const string &k) const; 

當然,如果你想與operator[]修改設置的容器,那麼你應該返回非const引用。

string& operator[](const string &k);