0

我不明白传递对象实例与传递取消引用对象之间的区别。我有

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()));

确实如此。

如果我无法更改要调用的方法,谁能告诉我为什么以及如何解决问题?

4

4 回答 4

3

在第一种情况下,您创建一个临时对象,并尝试将其传递给method.
临时对象不能被修改(修改它没有意义,它会在method返回的那一刻消失)。因此,要通过引用传递临时值,您必须通过const 引用传递。

void method(const A& a)
{

}
于 2013-02-22T22:23:50.427 回答
2

在这里,您正在创建一个临时对象:

method(A()); // A() here is creating a temporary
             //     ie an un-named object

您只能const&访问临时对象。
所以你有两个选择:

  1. 更改接口以获取 const 引用。
  2. 传递一个真实的对象。

所以:

// 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.
于 2013-02-22T22:23:54.560 回答
1

如果这是合法的,将会发生可怕的事情。考虑:

void addOne(double& j) { ++j; }

int q = 10;
addOne(q);

这将创建一个临时的double,向其中添加一个,并保持原始q不变。哎哟。

如果method修改其参数,您的代码将被破坏。如果没有,它应该const参考。

于 2013-02-22T22:27:43.817 回答
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++ 中的左值

于 2013-02-23T00:14:31.180 回答