繁体   English   中英

重载const运算符时使用const_iterator []

[英]Using const_iterator when overloading a const operator[]

我真的不明白下面我在做什么错。 我有一个名为Settings的类,具有下面列出的结构,以及下面列出的两个功能。 我遇到的麻烦是,在重载函数内重载const运算符[]时,将const修饰符放在哪里。 我需要在某个地方使用const_cast吗? 我想念什么?

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;
}

提前致谢。

如果您的函数getValue()修改了成员itc,则它不能是const(除非itc是可变的)。 我建议您在函数getValue()中声明itc:

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

c ++中的operator []具有两个含义:
(1) a[i] = x; //store x into a in position i a[i] = x; //store x into a in position i
(2) x = a[i]; //load a in position i to x 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;

您的问题不是const,而是引用。
同样,您在类中的声明必须与您在定义函数时使用的定义完全匹配。

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;
}

在您的声明中:

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

原型声明后的const只是告诉您operator[]不会修改对象,因此它与方法operator[]的代码有关,而与它的用法无关。 因此, const_iterator应该在operator[]代码中定义为局部变量。

返回类型上的const避免了您修改临时值(返回类型)的可能性。 为了提高效率,您可以通过返回const引用来获得相同的结果。

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

当然,如果要使用operator[]修改“设置”容器,则应返回非const引用。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM