我没有区分传递对象的实例与传递解除引用的对象。我有
class A
{
public:
A() {}
void m() {}
};
void method(A& a)
{
a.m();
}
int main(int argc,char** argv)
{
method(A());
return 0;
}
上面的调用不适用于编译器错误:
In function 'int main(int, char**)':
error:no matching function for call to 'method(A)'
note: candidates are:
note: void method(A&)
note: no known conversion for argument 1 from 'A' to 'A&'
note: void method(B&)
no known conversion for argument 1 from 'A' to 'B&'
但如果我写
method(*(new A()));
确实如此。
如果我无法更改我想要调用的方法,有人可以告诉我为什么以及如何解决问题?
答案 0 :(得分:3)
在第一种情况下,您创建一个试图传递给method
的临时对象
无法修改临时对象(修改它没有意义,它会在method
返回时消失)。因此,要通过引用传递临时值,您必须通过 const引用。
void method(const A& a)
{
}
答案 1 :(得分:2)
您在这里创建一个临时对象:
method(A()); // A() here is creating a temporary
// ie an un-named object
您只能获得const&
临时对象
所以你有两个选择:
所以:
// Option 1: Change the interface
void method(A const& a) // You can have a const
// reference to a temporary or
// a normal object.
// Options 2: Pass a real object
A a;
method(a); // a is an object.
// So you can have a reference to it.
// so it should work normally.
答案 2 :(得分:1)
如果这是合法的,可能会发生可怕的事情。考虑:
void addOne(double& j) { ++j; }
int q = 10;
addOne(q);
这会创建一个临时double
,向其中添加一个,并保持原始q
不被修改。哎哟。
如果method
修改了其参数,则代码会被破坏。如果没有,则应采用const
引用。
答案 3 :(得分:1)
您看到的问题是您的函数只接受A类型的左值。要解决此问题,您可以将函数更改为按值接受类型A:
void method( A a ) {}
或通过const引用:
void method( const A &a ) {}
或通过右值引用(如果使用C ++ 11):
void method( A &&a ) {}
或将类型A的左值传递给您的方法:
A a; method( a );
如果你想更深入地了解这个问题,请阅读c ++中的lvalue