我是cpp语言的初学者。
最近我在很多类中看到两次声明两次相同的函数,例如:
int& operator[](size_t i) {
assert(i<size());
return _buf[i];
}
const int& operator[](size_t i) const {
assert(i<size());
return _buf[i];
}
功能有什么不同?为什么我需要第一个?在哪种情况下,第一个功能将起作用,在哪种情况下第二个功能将起作用?
答案 0 :(得分:2)
其中不是const
。让我把它放在某种背景下:
struct Foo{
int value = 0;
int& operator[](size_t i) {
std::cout << "non-const\n";
return value;
}
const int& operator[](size_t i) const {
std::cout << "const\n";
return value;
}
};
将在const
个实例上调用const
版本,而在非const
个实例上调用非const
。 E.g。
int main(){
Foo f;
int x = f[0];
f[0] = 3; // OK
const Foo g;
int x = g[0];
//g[0] = 3; // NOT OK
}
...将打印
non-const
const
实际上两种方法都应该相同,主要区别在于const
版本返回const
引用,而非const
返回允许修改值的引用。< / p>
正如您所正确观察到的,除了const
和返回类型之外,两者是相同的。为避免重复代码,有时使用小技巧并根据非const
编写const
版本是有意义的:
const int& operator[](size_t i) const {
std::cout << "const\n";
return const_cast<Foo*>(this)->operator[](i);
}
有关完整示例,请参阅here。
答案 1 :(得分:1)
第一个重载表明下标操作符可以修改类实例的内部,后者表明类实例的内部是只读的,因此无法修改。
实际上,这意味着this
指针指向const
或non-const
对象。
<强>以前强>:
您使用C
标记了您的问题是不正确的,因为C不提供任何类成员函数,因此在全局函数声明之后AFAIK,const
是非法的。
答案 2 :(得分:1)
通常,如果用户标记为 const ,则不希望用户以某种方式更改对象。
这意味着如果您有一个提供 operator [] 的类,您不希望让用户通过 operator []更改此类对象的内部状态如果这些对象是 const 。
这就是为什么你有两个重载的原因。如果对象是 const ,那么版本
const int& operator[](size_t i) const
被调用。此版本返回const int&
,因此您无法进行任何修改。
相反,如果对象未标记为 const ,则
int& operator[](size_t i)
调用,您可以通过返回的引用自由修改对象的内部状态。
答案 3 :(得分:1)
区别在于const
关键字:
INT&安培; operator [](size_t i){(1)
const int&amp; operator [](size_t i) const {(2)
第一个函数返回对象的引用,这意味着您可以修改对象(例如,通过执行foo[0] = bar
。
第二个使用const
关键字两次:const int&
表示您返回一个无法修改的const引用。第二个const用于指定此函数不会修改对象。
您需要这两个版本,因为(1)用于修改集合的元素,(2)用于const对象:
你可以这样做:
void foo(std::vector<int> const& v) {
int j = v[0];
}
因为vector是一个看起来像(2)
的运算符答案 4 :(得分:0)
这意味着你的班级正在为两件事提供支持,
int& operator[](size_t i)
,因为最后没有const
限定符。
const int& operator[](size_t i) const
,因为最后有const
限定符。