2013-02-22 84 views
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())); 

它。

任何人都可以告訴我爲什麼以及如何解決問題,如果我不能改變我想打電話的方法?

+2

(非常量)引用無法綁定到臨時值。 – 2013-02-22 22:23:18

+0

@KerrekSB:既然你發佈了這個評論,請提供dup;) – 2013-02-22 22:23:51

+0

@honk:「* * dup」? :-) – 2013-02-22 22:24:34

回答

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. 
3

在第一種情況下,您創建了一個臨時對象,您嘗試傳遞給method
臨時對象不能被修改(修改它是沒有意義的,它會在method返回時消失)。因此,要通過臨時引用,您必須通過const引用

void method(const A& a) 
{ 

} 
+0

好吧,這是有道理的,但爲什麼GCC不告訴我,在錯誤中出現_const_的方式? – user1760653 2013-02-22 22:30:03

+0

@ user1760653因爲它不知道你在做什麼,它只知道你在做什麼。 – Xymostech 2013-02-22 22:32:29

+0

@ user1760653,因爲GCC看到的只是你試圖用'void method(const A&)'調用一個函數。但沒有宣佈。 – StoryTeller 2013-02-22 22:32:58

1

如果這是合法的,可怕的事情會發生。試想一下:

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

int q = 10; 
addOne(q); 

這將創建一個臨時double,添加一個到它,並留下您的原q不變。哎喲。

如果method修改了它的參數,你的代碼就被破壞了。如果沒有,則應採用const參考。

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