2016-02-11 85 views
1

在下面的例子中,test.cpp臨時打印地址?

#include <iostream> 
using namespace std; 

class Rectangle { 
    public: 
    int w, h; 
    Rectangle() : w(7), h(0) {} // constructor definition. 
    Rectangle(int x, int y) : w(x), h(y) {} // constructor definition. 
}; 


class MyClass { 
    public: 
    Rectangle trec; 
    MyClass() { 
    } 
    Rectangle getRect() { 
     return trec; 
    } 
}; 

int main() { 
    MyClass a = MyClass(); 
    cout << &a.getRect() << endl; 
} 

...我gcc test.cpp -o test.exe編譯時出現此錯誤:

test.cpp: In function ‘int main()’: 
test.cpp:32:22: error: taking address of temporary [-fpermissive] 
    cout << &a.getRect() << endl; 

我真的不明白什麼是暫時的在這裏 - a被實例化時cout運行,所以a.trec也應該實例化,並有一個地址,這正是getRect()返回? (或不復製得到隱含在return創建的,因爲返回類型被定義爲Rectangle,而不是Rectangle*?)

在任何情況下,我想檢查原來這樣寫的代碼,並在a.trecprivate,所以getRect()是我可以在我的代碼中使用的唯一東西 - 任何機會在這種情況下打印a.trec的地址?

+0

一個'Rectangle'是暫時的。 – PSkocik

回答

7

getRect()被定義爲

Rectangle getRect() { 
    return trec; 
} 

即使trec不是臨時trec實際上不是要返回什麼。由於您按價值歸還,因此您需要複製trec並將其放入函數返回中。該副本是一個臨時的,你不能把它的地址。

如果你改變了代碼

Rectangle& getRect() { 
    return trec; 
} 

const Rectangle& getRect() { 
    return trec; 
} 

現在我們指的a的成員,我們可以採取參考的地址。

+0

感謝你,@NathanOliver--換句話說,如果lib是這樣寫的,那麼我就沒有機會在不更改庫代碼的情況下訪問'a.trec'的地址。乾杯! – sdaau

+2

@sdaau正確。有些方法可以「破解」界面來獲得它,但我不會建議它,因爲它根本不是可移植的。 – NathanOliver

2
Rectangle getRect() { 
     return trec; 
    } 

返回trec的副本。您不保存此副本並嘗試獲取臨時地址,這是非法的。

可以改爲返回引用(或指針,只是不反引用),然後打印出該地址:

Rectangle& getRect() { 
     return trec; 
    } 
+0

謝謝你,@JameyD - 你是第一個,但我認爲接受的答案是更詳細一點;乾杯! – sdaau