Reputation: 75
I'm learning C++ and have a problem working with an object returned as a reference which I want to continue to use and modify.
I have two classes, University and Student.
University is instantiated and has method addStudent() which stores a new Student object in a private vector data member of University. I want the method to return a reference to the newly created Student object. I then want to call the Student::addCourse() method on the returend object to add some courses to the student's "transcript."
I thought that since I returned a reference to the Student object it would update itself stored in the _Students vector in the University object, and therefore the changes would be visible outside its scope, but it doesn't keep the changes.
When I call printTranscript() on the returned Student object, it properly shows the added courses.
But, when I call printRegistrar() on the University object, it shows that student has no courses.
This seems like I'm missing a fundamental OOP principle. What am I doing wrong, and how do I make it work?
(I already have this working using a student ID as a handle to reference a student between objects, but I thought this way seemed more elegant, if I could get it to work.)
The full code is here: 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();
Upvotes: 3
Views: 125
Reputation: 814
Student Bob = UHD.addStudent("Bob");
This call triggers the copy constructor, and hence returns a copy of "Bob", but not the actual object you added to UHD.
Upvotes: 0
Reputation: 110778
UHD.addStudent("Bob")
The result of this expression is indeed a reference to the internal Student
object.
Student Bob = UHD.addStudent("Bob");
Here, however, you are copying from that reference to construct the object Bob
. If you want to continue to keep a reference, you need to make Bob
a reference:
Student& Bob = UHD.addStudent("Bob");
Note, however, that Bob
may not remain a valid reference for long. At most you can expect it to last until the UHD
object is around, but adding new students may cause the vector to reallocate its elements, in which case the reference is no longer referring to a valid object. As @tenfour suggests in the comments, a std::list
would avoid that problem because it does not reallocate its elements. However, I would suggest that leaking references to your internal objects is a bad way to do things anyway, and would instead suggest having a way of modifying the internal Student
objects through the University
interface (perhaps just a simple setter).
Upvotes: 4