[英]Why do I need twice the same function?
我是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];
}
函数之间有什么区别? 为什么我需要第一个? 在哪些情况下第一个功能将起作用,在哪些情况下第二个功能将起作用?
在这些const
,另一个不是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
实例上调用。 例如
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
返回允许修改值的引用。
正如您正确观察到的那样,除了const
和返回类型外,两者是相同的。 为了避免重复代码,有时可以使用一个小技巧,并使用非const
来编写const
版本:
const int& operator[](size_t i) const {
std::cout << "const\n";
return const_cast<Foo*>(this)->operator[](i);
}
完整示例参见此处 。
第一个重载指出下标运算符可以修改类实例的内部,而第二个重载则指出类实例的内部是只读的,因此不能被修改。
实际上,这意味着this
指针指向const
non-const
对象。
先前 :您用C
标记了问题,这是不正确的,因为C不提供任何类成员函数,因此在全局函数声明后AFAIK, const
是非法的。
通常,如果用户将对象标记为const,则不希望它们以某种方式更改。
这意味着,如果您有一个提供operator []的类,那么如果这些对象是const ,则不希望用户通过operator []来更改此类对象的内部状态。
这就是为什么您有两个重载。 如果对象是const ,则版本
const int& operator[](size_t i) const
叫做。 此版本返回const int&
,因此您无法进行任何修改。
相反,如果对象未标记为const ,则
int& operator[](size_t i)
调用,您可以通过返回的引用自由修改对象的内部状态。
区别在于const
关键字:
int&运算符[](size_t i){(1)
const int&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];
}
因为矢量作为运算符看起来像(2)
这意味着您的班级正在为两件事提供支持,
非常量对象将调用int& operator[](size_t i)
,因为最后没有const
限定符。
const int& operator[](size_t i) const
将被const对象调用,因为最后有const
限定符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.