2014-03-02 36 views
3

我正在學習C++,並且遇到了一個問題,使用返回的對象作爲我想繼續使用和修改的參考。C++ OOP基礎知識 - 正確返回對象引用?

我有兩個班級,大學和學生。

大學被實例化並具有方法addStudent(),它將新的Student對象存儲在大學的專用矢量數據成員中。我想讓該方法返回對新創建的Student對象的引用。然後我想調用returend對象上的Student :: addCourse()方法來爲學生的「成績單」添加一些課程。

我認爲,因爲我返回對Student對象的引用,它會更新自身存儲在University對象的_Students矢量中,因此這些更改將在其範圍外可見,但不會保留更改。

當我在返回的Student對象上調用printTranscript()時,它正確顯示添加的課程。

但是,當我打電話給printRegistrar()對象時,它顯示學生沒有任何課程。

這似乎是我錯過了一個基本的面向對象的原則。我做錯了什麼,以及如何使它工作?

(我已經有這方面的工作使用學生證作爲手柄來引用對象之間的學生,但我認爲這樣顯得更優雅,如果我能得到它的工作。)

完整的代碼這裏:http://pastebin.com/cjmC1UuL

// Create a new university called UHD. 
University UHD; 

// Add 4 students to UHD. 
UHD.addStudent("Jim"); 
UHD.addStudent("Bill"); 
Student Bob = UHD.addStudent("Bob"); 
UHD.addStudent("Greg"); 

// Add 3 classes for Bob 
Bob.addCourse("WRTG140"); 
Bob.addCourse("MATH009"); 
Bob.addCourse("BIOL101");  


// Shows Bob correctly has 3 classes. 
Bob.printTranscript(); 

// BUG?: Shows Bob incorrectly has 0 classes. 
UHD.printRegistrar(); 

回答

4
UHD.addStudent("Bob") 

該表達式的結果確實是內部Student對象的引用。

Student Bob = UHD.addStudent("Bob"); 

但在這裏,你是從參考複製到構造對象Bob。如果你想繼續保持一個參考,你需要做Bob參考:

Student& Bob = UHD.addStudent("Bob"); 

但是請注意,這Bob可能不會保持長期有效的參考。至多可以預期它持續到UHD對象周圍,但添加新學生可能會導致向量重新分配其元素,在這種情況下,引用不再引用有效對象。正如@tenfour在評論中指出的那樣,std::list可以避免這個問題,因爲它不會重新分配它的元素。但是,我建議泄漏對內部對象的引用無論如何都是一種不好的方式,而是建議通過University接口(可能只是一個簡單的setter)修改內部對象。

+1

長時間保持這個參考也是不安全的;我認爲'list'是一個更好的選擇,所以參考不會移動 – tenfour

+1

@tenfour是的。事實上,他們可能已經有了這個問題,因爲他們在添加一個他們參考的「學生」之後添加了另一個「學生」。 –

+0

週末失去一個人物。真棒。謝謝。 :) – paper

0
Student Bob = UHD.addStudent("Bob"); 

此調用觸發複製構造函數,因此返回「Bob」的副本,但不是您添加到UHD的實際對象。