Advertisement

Copy Constructor

Started by May 13, 2002 06:29 PM
15 comments, last by Tac-Tics 22 years, 9 months ago
As I understand it, there's some weird symbiotic relationship between a the "copy constructor" and the equal (=) operator for a class, because my program "seems" to work when I use the equal operator when I have only defined a copy constructor. *However*, when I use the equal operator, I need to free some dynamicly reserved memory (something a constructor won't let you do, since any memory already there is just uninitiated garbage data). Maybe it'd be easier if I drew a diagram (here's my source): String.h
    
/* yada yada yada... */

class String
{
	private:
		char* charList;
		int size;

	public:
		String ();
		String (String& s);
		~String ();

                /* yada yada yada... */


		void operator= (String s);
                 
                /* yada yada yada... */
};
  
String.cpp
  
/* yada yada yada...*/

/*
	Creates an empty String
*/
String::String ()
{
	size = 0;
}

/*
	Creates a copy of another String object.
*/
String::String (String& s)
{
	this->size = s.size;
	charList = new char[size];

	for (int i = 0; i < size; i++)
	{
		charList = s.charList;
	}
}

/*
	String Destructor. Liberates allocated memory.
*/
String::~String ()
{
	delete charList;
}

/* yada yada yada…*/

/*
	Assignment operator. Sets a String equal to the given String.
*/</font>
<font color="blue">void</font> String::operator= (String& s)
{
	size = s.size;
        <font color="blue">delete</font> charList;
	charList = <font color="blue">new</font> char[<font color="purple">size</font>];

	<font color="blue">for</font> (<font color="blue">int</font> i = 0; i &lt; size; i++)
	{
		cout &lt;&lt; <font color="darkred">"s.charList[<font color="purple">"</font> &lt;&lt; i &lt;&lt; <font color="darkred">"</font>] = "</font> &lt;&lt; s.charList[<font color="purple">i</font>];
		charList[<font color="purple">i</font>] = s.charList[<font color="purple">i</font>];
	}
}
  </pre></DIV><!–ENDSCRIPT–> 

If you need any more info to help me, don't hesitate to ask.

vv Edit Notice vv


<SPAN CLASS=editedby>[edited by - Tac-Tics on May 13, 2002 7:32:39 PM]</SPAN>    
Let me get one thing out of the way before I (try to) answer your question. Are you writing a string class because you want to or because you need one? If the latter is the case, use std::string.

Are you worried that charList might not be a valid pointer when you try to delete it in the assignment operator? If so, just initialize it to 0 in the constructor and then do a "if charList ..." in your assignment operator.
Advertisement
Instead of

size = s.size;
delete charList;

you should have

if (size) delete charList;
size = s.size;

How do you assign a char * to String, btw?

Edit: forgot to mention that your copy constructor and assignment operators should take const references.

[edited by - IndirectX on May 13, 2002 8:58:05 PM]
---visit #directxdev on afternet <- not just for directx, despite the name
Well, I (finally) figured it out. Thanks for the replies though.

The reason I''m writing my own string class is because I don''t particularly like using C-style strings and I do not particularly like the standard library. So instead of spend hours STFW for scraps of cloudy documentation on it, I decided to take what I know and make one I like better (this one''s more like Java''s String class, which I am more comfortable with). So far I''m pretty pleased with the results. I can create a String object out of both char* and std::string objects and I can also convert them back when I need either one.

As for changing a char* to a String, I just allocated enough space for it, then I loop through and copy all the chars up until the ''\0'' byte.
*mute*

[EDIT] I'll be making a general post some time today about my Beginners Forum policy - Michalson.


[edited by - Michalson on May 14, 2002 6:49:28 AM]
quote:
[EDIT] I'll be making a general post some time today about my Beginners Forum policy - Michalson.

I'm sorry you feel it necessary to allow newbies to persist with counter-productive and uninformed methods.


[ C++ FAQ Lite | ACCU | Boost | Python | Agile Manifesto! ]

[edited by - SabreMan on May 14, 2002 3:25:10 PM]
Advertisement
>>
I''m sorry you feel it necessary to allow newbies to persist with counter-productive and uninformed methods.

Hrmm... well, with that comment I can pretty much infer what was said. Unfortunately, I do not agree with you. I don''t see how making my own String class is "counter-productive," though the phrase "reinventing the wheel" may apply. I challenge you to find anything suggesting the experience of creating such a class is counter-productive in any way. I''m sorry if my methods are different from yours in learning it, but I feel I have a good sense of how to go about learning new things.

(and to tell you the truth, the only reason I''m making it is because I don''t like underscores-style used by the various STD functions =-P )
The primary reason your post was edited was due to your use of the word "stupid" in decribing both the original poster and his question. I will be explaining my policy for this forum shortly (today), at which time I invite you to express whatever opinions you have. Until then please refrain from any further off topic discussion in this thread.
Considering the function:
String foo(const String & str){  String temp = str;  ...  return temp;}...// some where in some functionString tempstr;tempstr = foo(somestr);... 


It might still works on your own String class. However imagine how much new/delete are called? Performance isn''t good on this case, especially when you does this often in a loop.

I suggest spicing up your own String class with some copy-on-write features might be good.

Btw, add a check in your assignment where it sometime accidentally assign to itself..er... :
somestr = somestr; 


"after many years of singularity, i'm still searching on the event horizon"
Two points that seem to have not been addressed. The assignment operator is one of the few functions where a default behavior exists even if you don''t define it for your class. If there is no function defined, operator= simply does a member-wise copy. The relationship between the copy-constructor and the assignment operator is that they have the same purpose (copying members) and so often one can be implemented in terms of the other.

Second, there is a minor logical error in the source presented by Tac-Tics. Since ''charList'' is a pointer to an array, it must always be deleted using brackets like so: ''delete [] charList;''. This is the only way that the compiler knows that there is a whole array of chars to be deleted as opposed to just a single one.

A final note, Tac-Tics is to be commended for taking the time to implement their own string class. The best way to learn about any data structure, especially its limitations and when it is appropriate to use, is to implement that data structure at least once. This is the best way to learn programming.

-D

This topic is closed to new replies.

Advertisement