Const引用有时会导致混淆

Const references sometimes lead to confusion

本文关键字:引用 Const      更新时间:2023-10-16

我是C++的新手。我了解到引用应该在任何可能的时候使用,指针应该只在绝对必要的时候使用。我还了解到,当函数不更改引用的变量时,函数参数中应该使用const引用。

我理解原因并同意他们的观点,但有一种常见的情况是,const引用会导致混淆,即可变对象"变得不可变",这是对对象声明const引用的结果(常量(。例如,Foo类有一个名为incrementX()的方法,该方法在调用时会使Foo的状态发生变化:

class Foo {
    public:
        void incrementX();
    private:
        private int x;
}
void Foo::incrementX() {
    x++;
}
class Bar {
    public:
        void doSomethingWith(const Foo &foo);
}
void Bar::doSomethingWith(const Foo &foo) {
    foo.incrementX(); // <- illegal because incrementX() is not a const method
}
int main() {
    Foo foo;
    Bar bar;
    bar.doSomethingWith(foo);
}

通常的解决方案是将incrementX()声明为const方法,这反过来又迫使我将变量x声明为mutable变量。问题是,通过将incrementX()转换为const方法,我是说这个方法不应该改变对象的状态,这在上面的例子中是不正确的。这不仅不是真的,而且该方法的意图是改变对象的状态。

我很好奇有经验的C++程序员是如何处理这种情况的。在这种情况下,我倾向于使用const指针(Foo * const foo(,这会被推荐/劝阻吗?

谢谢。

EDIT:为了澄清我困惑的原因,我经常听到人们说"当函数承诺不更改参数时使用const-refs">,但"更改参数">到底是什么意思?这是否意味着函数承诺不向参数分配新对象,还是意味着它不会改变对象的状态?当然,const引用不允许这两种更改,但对于const引用,主要关注的是什么是因为它不会为参数分配新值,还是因为它不会改变const引用所引用对象的状态?

通过const Foo &

void Bar::doSomethingWith(const Foo &foo)

承诺不修改CCD_ 19。因此,它可能不会调用它的非常量incrementX方法。

如果您有Bar::doSomethingWith(Foo &foo)需要调用foo.incrementX(因此需要采用它的参数非常量引用(,那么您应该重新考虑作为Bar的方法而不是Foo的方法是否真的合适。

如果您希望更改对象,请不要传递const引用,或者重载函数以获得doSomethingWith(const Foo&)doSomethingWith(Foo&)

整个想法是通过const引用强制const行为,因此您只能调用标记为const的成员函数,从长远来看,这会减少问题。

附言:我让doSomething成为Foo的一员。

示例:

#include <iostream>
using namespace std;
class Foo
{
    int m=0;
public:
    void doSomething(const Foo& foo) const
    {
        cout << "calling const reference" << endl;
    }
    void doSomething(Foo& foo)
    {
        cout << "calling reference" << endl;
        foo.m++;
    }
};

int main()
{
    const Foo f,g ;
    f.doSomething(g); // calls const reference
    Foo h,k;
    h.doSomething(k); // calls reference
}
相关文章: