const成员函数
我有下面这段代码:
const成员函数
class Test{
private:
int id;
public:
Test(int v):id(v) {}
int getId() { return id;}; // however,I change this method signature
int getId() const { return id;};
and all the errors gone
};
struct compare{
bool operator()(const Test& t1, const Test& t2){
return t1.getId() < t2.getId(); // got error here
}
};
int main(int argc, char *argv[]){
set<Test, compare> s;
Test str[] = {Test(1), Test(2), Test(3)};
for (int i = 0; i < 3; ++i){
s.insert(str[i]);
}
for (set<Test>::iterator it = s.begin(); it != s.end(); ++it){
cout << it->getId() << "\n"; // got error here
}
return EXIT_SUCCESS;
}
我得到这个错误,当我调用的方法的getId()与代码:
passing `const Test' as `this' argument of `int Test::getId()' discards qualifiers
我不知道为什么我需要const getId()方法来修复该错误?谢谢
bool operator()(const Test& t1, const Test& t2)
您的操作员需要参考const Test
对象。您只能通过对const
限定类型的引用来调用const
合格的成员函数。
set<Test>::iterator it = s.begin()
std::set
的元素是不可变的:您无法更改它们。因此,迭代器到std::set
始终是const
限定类型的对象。
const Test& t1
使t1
不变,也就是说,它不能通过该引用进行更改。现在,您对该对象调用的任何函数都可能改变其内部状态 - const
不允许!
这是怎么解决的?只需将不会改变内部状态的函数标记为const
!这意味着,它们可以在const对象/引用/指针上调用。
这就是为什么你需要const
后getId
函数,以确保你不会改变任何内部状态。
int getId() const { return id;};
编辑:当然,这同样适用于std::set
,但我不会去,作为其他的答案已经这样做了。
的set::iterator
只给出const
访问元素,变化可能会影响集合中元素的相对顺序 - 不变的,它需要保护(也就是说,如果你在设置更改元素,可能会损坏的假设排序设置中的元素,以及未来的查找,插入等将不会如预期的那样可靠地工作)。因此,只有const
成员函数可以通过iterator
对元素访问进行调用。
这有点令人困惑,因为对于其他一些容器,const_iterator
与iterator
的选择决定了授予的访问权限。
你只能在const对象上调用const成员函数。
set<Test>::iterator it = s.begin();
返回一个const对象,所以你只能调用这个对象的const类型的成员函数。
真的,'* it'返回一个const对象。迭代器本身不是'const'。 – 2011-05-18 04:12:08
运算符()在其参数列表中有const Test&
对象,因此当您通过const对象调用时,需要使用const限定符声明您的函数。
int getId() const { return id;};
另外改变,
for (std::set<Test, compare>::const_iterator it = s.begin(); it != s.end(); ++it){
std::cout << it->getId() << "\n"; // got error here
}
关于“迭代器一个std ::组总是到对象的常量限定类型。”:即在C的任何版本指定被++标准或这取决于标准库开发人员? – 2011-05-18 04:03:36
@Eugen:它在标准的第23.2.4p6节中指定(在C++ 0x中,编号可能在早期版本中有所不同)。 – 2011-05-18 04:11:17
@Eugen:在(C++ 0x FDIS)中指定23.2.4 p5关联容器中的键是不可变的&p6'对于关联容器,其中 的值类型与键类型相同,迭代器和const_iterator都是常量迭代器“。 – Xeo 2011-05-18 04:14:41