我真的不明白我下面做错了什么。我有一个名为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;
}
提前致谢。
答案 0 :(得分:0)
如果你的函数getValue()修改成员itc,那么它不能是const(除非itc是可变的)。我建议你在函数getValue()中声明itc:
...
const map<string, string> m = settingsMap;
imap<string, string>::const_iterator itc = m.begin();
...
答案 1 :(得分:0)
c ++中的operator []有两个含义:
(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);
[注意这里的参数是{{ 1}}而不是const string
,因为它可能不应该被更改。另外,由于输出字符串不应该被更改,因此它也应该被定义为string
。
第二个,应该返回const
,而不是string
,所以你应该放弃第一个const string
:const
[因为原来的结构这个操作不会改变,最后string operator[](const string) const;
是好的,应该保留]。另请注意,参数为const
而不是const string
,因为您不希望更改参数。
在您的情况下:您似乎想要string
的第二个含义,因此您应将其声明为:operator[]
答案 2 :(得分:0)
你的问题不在于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;
}
答案 3 :(得分: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
原型声明后的const只是告诉你operator[]
没有
修改对象,因此它与方法operator[]
中的代码有关,并且
不是它的用法。因此,const_iterator
应该在operator[]
代码中定义为局部变量。
返回类型的const避免了修改临时值(返回类型)的可能性。为了提高效率,可以通过返回const引用来获得相同的结果。
const string& operator[](const string &k) const;
当然,如果要使用operator[]
修改“设置”容器,则应返回非const引用。
string& operator[](const string &k);