我是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
引用引用的对象的状态?
答案 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
}