繁体   English   中英

为什么我需要两次相同的功能?

[英]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.

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