944,141 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Unsolved
  • Views: 16241
  • C++ RSS
Jan 18th, 2006
0

(C++) Writing a Copy Constructor?!?

Expand Post »
Hello ladies and gents,

I'm trying to include a copy constructor and an assignement operator into this code wich has two separate classes, the idea is to copy the last name that was entered. Problem is, I can't seem to grasp how to get acces to the copy constructor in main nor am I sure that the copy constructor is written correctly?

Could someone help me out with this program:
C++ Syntax (Toggle Plain Text)
  1. //Lobby
  2. //Simulate a lobby where people wait
  3.  
  4. #include <iostream>
  5. #include <string>
  6.  
  7. using namespace std;
  8.  
  9. class Person
  10. {
  11. public:
  12. Person(const string& name = ""):m_Name(name), m_pNext(NULL){}
  13. Person(const Person& copyName);
  14. string GetName() const { return m_Name;}
  15. Person* GetNext() const { return m_pNext;}
  16. void SetNext(Person* next) { m_pNext = next;}
  17.  
  18. private:
  19. string m_Name;
  20. Person* m_pNext; // pointer to next name in list
  21. };
  22.  
  23. Person::Person(const Person& copyName)
  24. {
  25. cout << "Copy constructor called...\n";
  26.  
  27. m_pNext = new Person;
  28. *m_pNext = copyName.GetName();
  29. }
  30.  
  31. class Lobby
  32. {
  33. friend ostream& operator<<(ostream& os, const Lobby& aLobby);
  34.  
  35. public:
  36. Lobby():m_pHead(NULL){}
  37. ~Lobby() { Clear();}
  38.  
  39. void AddName();
  40. void RemoveName();
  41. void Clear();
  42.  
  43. private:
  44. Person* m_pHead;
  45. };
  46.  
  47. void Lobby::AddName()
  48. {
  49. //create a new name node
  50. cout << "Please enter the name of the new person: ";
  51. string name;
  52. cin >> name;
  53. Person* pNewName = new Person(name);
  54.  
  55. //if list is empty, make head of list this new name
  56. if (m_pHead == NULL)
  57. {
  58. m_pHead = pNewName;
  59. }
  60. //otherwise find the end of the list and add the name there
  61. else
  62. {
  63. Person* pIter = m_pHead;
  64.  
  65. while (pIter->GetNext() != NULL)
  66. {
  67. pIter = pIter->GetNext();
  68. }
  69. pIter->SetNext(pNewName);
  70. }
  71. }
  72.  
  73. void Lobby::RemoveName()
  74. {
  75. if (m_pHead == NULL)
  76. {
  77. cout << "The lobby is empty. No one to remove.\n";
  78. }
  79. else
  80. {
  81. Person* pTemp = m_pHead;
  82. m_pHead = m_pHead->GetNext();
  83. delete pTemp;
  84. }
  85. }
  86.  
  87. void Lobby::Clear()
  88. {
  89. while (m_pHead != NULL)
  90. {
  91. RemoveName();
  92. }
  93. }
  94.  
  95. ostream& operator<<(ostream& os, const Lobby& aLobby)
  96. {
  97. Person* pIter = aLobby.m_pHead;
  98.  
  99. os << "\nHere's who's in the lobby:\n";
  100.  
  101. if (pIter == NULL)
  102. {
  103. os << "The lobby is empty.\n";
  104. }
  105. else
  106. {
  107. while (pIter != NULL)
  108. {
  109. os << pIter->GetName() << endl;
  110. pIter = pIter->GetNext();
  111. }
  112. }
  113. return os;
  114. }
  115.  
  116. int main()
  117. {
  118. Lobby myLobby;
  119. int choice;
  120.  
  121. do
  122. {
  123. cout << myLobby;
  124. cout << "\nLOBBY\n";
  125. cout << "0 - Exit the program.\n";
  126. cout << "1 - Add a person to the lobby.\n";
  127. cout << "2 - Remove a person from the lobby.\n";
  128. cout << "3 - Clear the lobby.\n";
  129. cout << "4 - Copy the last name.\n";
  130. cout << endl << "Enter choice: ";
  131.  
  132. cin >> choice;
  133.  
  134. switch(choice)
  135. {
  136. case 0:
  137. cout << "Good-bye.\n";
  138. break;
  139. case 1:
  140. myLobby.AddName();
  141. break;
  142. case 2:
  143. myLobby.RemoveName();
  144. break;
  145. case 3:
  146. myLobby.Clear();
  147. break;
  148. //case 4:
  149. //Person. //<-- how to write the link to getting
  150. //break; //the copy???
  151. default:
  152. cout << "That was not a valid choice.\n";
  153.  
  154. }
  155. } while (choice != 0);
  156.  
  157. cout << "Press enter to exit!\n";
  158.  
  159. cin.ignore(1, '\0');
  160.  
  161. return 0;
  162. }

Thank you.
Similar Threads
Reputation Points: 51
Solved Threads: 4
Posting Pro in Training
JoBe is offline Offline
420 posts
since Sep 2004
Jan 18th, 2006
0

Re: (C++) Writing a Copy Constructor?!?

C++ Syntax (Toggle Plain Text)
  1. Person::Person(const Person& copyName) :
  2. {
  3. cout << "Copy constructor called...\n";
  4.  
  5. m_name= copyName.GetName();
  6. m_pNext = 0; //or m_pNext = copyName.m_pNext; if you want both copies to have the same address in their pointers.
  7. }
Reputation Points: 718
Solved Threads: 373
Nearly a Posting Maven
Lerner is offline Offline
2,253 posts
since Jul 2005
Jan 18th, 2006
0

Re: (C++) Writing a Copy Constructor?!?

Thanks for the help Lerner, but how do I call the copy constructor in main when I want to copy the last name that was entered then?

And also, could the copy constructor be written for the Lobby class aswell?

Thanks.
Reputation Points: 51
Solved Threads: 4
Posting Pro in Training
JoBe is offline Offline
420 posts
since Sep 2004
Jan 18th, 2006
0

Re: (C++) Writing a Copy Constructor?!?

if you had a Person, p, in main() and wanted to copy p into Person p1 using a copy constructor then you could do this:

Person p1(p);

If p1 already exists in main() and you want to copy something else into p1 after it's already been constructed, then you could write a copy method in addition to a copy constructor. Say you are given a Person in the form of Person pointer, *pPerson, and you wanted to copy it into an existing Person, p1, rather than having p1 be a copy of p. Then it would be:

p1.copyPerson(*pPerson);

where copyPerson() was a method of the Person class taking a Person parameter and copying the data into another Person.

Yes, you can/should implement a copy constructor for the Lobby class. In fact, the compiler will do it for you if you don't do it. To my knowledge, all classes need at least a non-copy constructor, a copy contstructor, a destructor, and an assignment operator. If you don't write one of each for your class/struct, the compiler will do it for you, and you may not like the results, or you may say thank you very much and leave it go at that, depending on the situation.
Reputation Points: 718
Solved Threads: 373
Nearly a Posting Maven
Lerner is offline Offline
2,253 posts
since Jul 2005
Jan 20th, 2006
0

Re: (C++) Writing a Copy Constructor?!?

Why not use the assignment operator rather than the CopyPerson() method?

Actually most classes will work perfectly will with the compiler generated copy constructor, destructor & assignment operator.
Only classes which do their own resource mgmt need them.

In the case of People & Lobby classes, the design is overly complicated by incorporating the 'list' into both classes.
eg what should happen when a People object is destroyed?
should it be removed from the linked chain?
What if the obj is a copy of an obj which is in the list?
etc...

Why not use a list<People> or vector<People> in the Lobby class & remove this complication from the People class?
Reputation Points: 10
Solved Threads: 2
Newbie Poster
kon_t is offline Offline
17 posts
since Feb 2005
Jan 21st, 2006
0

Re: (C++) Writing a Copy Constructor?!?

Thanks for the additional help guys, but, I seem not to be able to grasp how to write this copy constructor or assignement operator for the program. No worries though, it was just an exercise I was trying to make from a book.

Why I wanted to do it the way I described is because it was written that way in that book and with that code, I had to write them. Suppose like you've said, there are better ways to solve this, though, would have like to be able to solve it the way it was asked in that book.

Darn, so frustrating from time to time when you can't seem to grasp how the hell that piece of code is supposed to fit into that program :rolleyes:

I'll put it aside and return to it again when I understand the meaning of it all abit better because for instance, to me, it seems a copy constructor and an assignement operator are the same thing. Difference I seem to see is that a copy constructor make a deep copy in wich it gives the object it's own adress and an assignement operator gives one object the value of another object, wich is the same as copying right

Pfff, so confusing from time to time :o
Reputation Points: 51
Solved Threads: 4
Posting Pro in Training
JoBe is offline Offline
420 posts
since Sep 2004
Jan 21st, 2006
0

Re: (C++) Writing a Copy Constructor?!?

Copy constructors and assignment operators frequently look and act a lot alike. The difference is that copy constructors create a new object given the data in an already existing object whereas the assignment operator assigns the data in one existing object into another existing object, meaning no new object is created in the process. Since it makes no sense to copy/assign the data of an object into itself, assignment operator code frequently checks for identity of rhs and lhs objects before proceeding, whereas with the copy constructor there is no existing object to use as an lhs object so there can't be identity. Otherwise, you can (frequently) copy the code of the copy constructor into assignment operator code.

The biggest problem in your code that I can see is the following line:

*m_pNext = copyName.GetName();

copyName.GetName() returns a string, whereas *m_pNext is a Person, not a string, so it's hard assigning a string to a Person. Change *m_pNext to m_name and the code looks pretty good to me (haven't compiled it though). Also, why use the new operator when implementing the Copy constructor. Copy constructors make new objects using static memory. If you want to use dynamic memory to create a new object, then use the new operator, as you do in the addName() method.
Reputation Points: 718
Solved Threads: 373
Nearly a Posting Maven
Lerner is offline Offline
2,253 posts
since Jul 2005
Jan 23rd, 2006
0

Re: (C++) Writing a Copy Constructor?!?

To answer my own question, you would use the new operator in the copy constructor if you wanted to create a deep copy instead of a shallow copy. A shallow copy is when the information is copied directly from the object to be copied into the new copy of the object. This means that if the object contains a pointer, that the new copy will contain the same address in the pointer that the old copy had. Thus you could change the information at the address in the pointer in the old copy by changing the information in the new copy. Sometimes this is what you want, and sometimes it isn't. You might want the data at the address of the pointer in the old copy to be copied into the new object so you can change it without changing the information in the old object. To do this you would populate the pointer in the new copy of the object with a new memory address using the new operator, and then copy the data from the old copy pointers address into the new copy's pointer address. This can create a problem in that you now have to release the memory that you allocated in the new copy of the object. That is usually done in the destructor. But if you call delete on a pointer whose memory wasn't allocated with the new operator and that isn't null you will have a problem. This c/would happen if an object created with the default constructor, or non-copy constructor doesn't allocate memory to the pointer contained therein with the new operator. So, often if you want to allocate memory in the copy constructor using the new operator so you can do a deep copy, then all constructors will use the new operator to allocate memory for the same pointer for their objects so the destructor can delete the dynamic memory from all objects created of that class, rather than trying to keep track of which objects are created by the copy constructor and contain dynamic memory that should be deleted manually and which objects are created by non-copy constructor(s) and therefore don't contain dynamic memory and shouldn't have memory deleted manually. Are there other ways to deal with this dilema besides having all constructors use dynamic memory if want to do deep copy with copy constructors; probably, but they are probably even more complicated.

How do you know what to do when, where? In my opinion, it's only through practice, but then maybe that's my rationalization for the incomplete/misleading information I had provided in my previous post (and this one too?).

Good luck. Keep reading. Keep coding.
Reputation Points: 718
Solved Threads: 373
Nearly a Posting Maven
Lerner is offline Offline
2,253 posts
since Jul 2005

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: C++ second largest problem
Next Thread in C++ Forum Timeline: I need help on a C++ program!!!!!!!!!!!!!!!!!!!!!!!





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC