Const引用有时会导致混淆

时间:2014-07-29 14:00:44

标签: c++ pointers reference const

我是C ++的新手。我了解到应尽可能使用引用,并且只有在严格必要时才应使用指针。我还了解到,当函数不更改引用变量时,应在函数参数中使用const引用。

我理解原因并同意它们,但有一个常见的情况是const引用导致混淆,即当一个可变对象变为不可变的时候#34;作为声明对象的const引用的效果(const-ness)。例如,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),是推荐/不鼓励吗?

感谢。

编辑:为了澄清我混淆的原因,我经常听到人们说&#34;当函数承诺不改变参数时使用const引用&#34; ,但是&#34;更改参数&#34; 意味着什么?这是否意味着函数承诺不为参数赋予新对象,或者它是否意味着它不会改变对象的状态?当然,const引用不允许这两种更改,但涉及const引用的主要问题是什么?是否它不会指定参数的新值,还是它不会改变const引用引用的对象的状态?

2 个答案:

答案 0 :(得分:1)

const Foo &

void Bar::doSomethingWith(const Foo &foo)

承诺不会修改foo。因此,它可能不会将其称为非const incrementX方法。

如果你有Bar::doSomethingWith(Foo &foo)需要调用foo.incrementX(因此需要将其参数作为非const引用),那么你应该重新考虑是否真的适合{{1}的方法首先是1}}而不是Bar

答案 1 :(得分:0)

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

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

PS:我让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
}