2011-09-24 66 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);