2011-05-11 55 views
3

我有以下代碼:用C++返回當前對象(* this)?

代碼1

class Student { 
    int no; 
    char grade[M+1]; 
public: 
    Student() { 
     no = 0; 
     grade[0] = '\0'; 
    } 
    void set(int n, const char* g) { 
     no = n; 
     strcpy(grade, g); 

    } 
    const Student getObject() { 
     return *this; 
    } 
    void display() const { 
     cout << no << ", " << grade << endl; 
    } 
}; 

代碼2:

// no change from code 1 
const Student& getObject() { 
     return *this; 
    } 
// no change from code 1 

正如本書我讀解釋裏getObject()代碼的區別1 2是代碼2的getObject()返回對當前對象的引用,而不是副本(出於效率的原因)。

測試代碼:

Student harry, harry1; 
    harry.set(123, "ABCD"); 

    harry1 = harry.getObject(); 
    harry1.set(1111,"MMMMMM"); 
    harry.display(); // Line 1 => displayed: 123, ABCD 
    harry1.display();/Line 2 => displayed: 1111, MMMMMM 

我不明白

然而,如下我已經測試(代碼2)。如果getObject()返回一個引用,那麼測試代碼中的第1行也應該顯示111,MMMMMM?因爲我認爲harry應該包含harry對象的地址? 還是我誤解了一些東西?

+0

這不僅僅是爲了提高效率。有時副本可能不可能。 – 2011-05-11 12:03:33

+0

將所有建議修改'harry1'爲'Student&' - 這不會作爲getObj()向Student返回一個** const ** ref,所以這不會被編譯。 – davka 2011-05-11 12:07:03

+0

閱讀有關賦值運算符。你正在像這樣使用'harry1 = harry.getObject();'。它將一個對象的值複製到另一個對象。 – 2011-05-11 13:30:23

回答

5

雖然harry.getObject()是原始對象的引用,然後分配毀了:

harry1 = harry.getObject(); 

執行的副本。

相反:

Student const& harry1 = harry.getObject(); 
+0

不會編譯。 :)'const'引用被返回。所以'const Student&harry1 = harry.getObject();'必須被使用。 – 2011-05-11 13:25:20

+0

@Serge:好點;謝謝。 – 2011-05-11 13:39:02

4

您正在將getObject返回的引用分配給Student,因此它會在代碼1(在從getObject返回時直接複製)後幾秒後被複制。使用

Student& harry1 = harry.GetObject(); 

獲得哈里的參考。請注意,您必須在一個步驟中聲明和初始化引用。

2

您正在使用實際對象,而不是指針或引用。當你說:

harry1 = harry.getObject() 

harry的內容被默認賦值運算符複製到harry1中。

1

harry1在你的測試代碼中是學生的一個實例,而不是一個參考。它改成這樣:

Student harry; 
harry.set(123, "ABCD"); 

Student& harry1 = harry.getObject(); 
harry1.set(1111,"MMMMMM"); 
harry.display(); // Line 1 => displayed: 123, ABCD 
harry1.display();/Line 2 => displayed: 1111, MMMMMM 
1

常見提醒:定義一個拷貝構造函數,私營和未實現:

private: 
    Student(Student& xOther); 

這樣,如果你碰巧有不必要的副本,編譯器會檢測到它們(您harry1實際上是一個副本)。如果您期望擁有副本,您可以正確控制它們的完成方式,從而避免混淆潛在的指針或封裝對象。