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

时间:2017-05-26 11:35:15

标签: c++

我是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];
    }

功能有什么不同?为什么我需要第一个?在哪种情况下,第一个功能将起作用,在哪种情况下第二个功能将起作用?

5 个答案:

答案 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指针指向constnon-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)

这意味着你的班级正在为两件事提供支持,

  • 非Const对象
  • Const对象
将为非const对象调用

int& operator[](size_t i),因为最后没有const限定符。

将为const对象调用

const int& operator[](size_t i) const,因为最后有const限定符。