Jun 13, 2011 at 6:21pm UTC
Also, const CString string was probably supposed to be const CString& string .
Without it, an unnecessary copy of the parameter will be made every time you call one of these functions.
Jun 13, 2011 at 6:23pm UTC
@Athar, I was just testing out my copy constructor. I'll make them all references now ;)
Still gives me a stupid Debug Error. Here's the whole program.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
#include<iostream>
#include<cstring>
class CString
{
public :
//Constructors
CString(const char * string)
{
str = new char [strlen(string)+1];
strcpy(str, string);
length = strlen(string+1);
}
CString(const CString& string)
{
str = new char [string.length+1];
strcpy(str, string.str);
length = string.length+1;
}
~CString()
{ delete [] str; }
CString& operator =(const CString string);
CString operator +(const CString& string) const ;
CString& operator +=(const CString& string);
void print() const ;
private :
char * str;
size_t length;
};
CString& CString::operator =(const CString& string)
{
if (this == &string) // return if the two are the same
return *this ;
delete [] str;
this ->str = new char [string.length+1];
strcpy(this ->str, string.str);
this ->length = string.length;
return *this ;
}
CString CString::operator +(const CString& string) const
{
char * temp = new char [this ->length];
strcat(temp, string.str);
CString concatenated(temp);
delete [] temp;
return concatenated;
}
CString& CString::operator +=(const CString& string)
{
this ->length += string.length;
char * temp = new char [this ->length+1];
strcat(temp, this ->str);
strcat(temp, string.str);
delete [] this ->str;
this ->str = temp;
return *this ;
}
void CString::print()
{
std::cout << str << std::endl;
return ;
}
int main(void )
{
char str[] = "Hello, world!" ;
char * pstr = str;
CString str1(pstr);
CString str2 = str1;
str1 += str2;
str2.print();
pstr = NULL;
return 0;
}
As for overusing
this ->
, just a bad habit I suppose :/
Last edited on Jun 13, 2011 at 6:33pm UTC
Jun 13, 2011 at 6:35pm UTC
Doesn't your debugger show you where the error occurs?
The first error points to the strcpy in line 17. This is likely caused by lines 12 and 18, which should be
length = strlen(string); and
length = string.length; , respectively.
The second error points to the strcat in line 59. This is because you use the newly allocated array uninitialized.
temp[0]='\0'; will make it an empty C string.
Jun 13, 2011 at 6:47pm UTC
Thank you Athar! I wasn't expecting the errors to be in the Constructor, good call! The + operator was much easier, so now the whole thing works :-)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
#include<iostream>
#include<cstring>
class CString
{
public :
//Constructors
CString(const char * string)
{
str = new char [strlen(string)+1];
strcpy(str, string);
length = strlen(string);
}
CString(const CString& string)
{
str = new char [string.length+1];
strcpy(str, string.str);
length = string.length;
}
~CString()
{ delete [] str; }
CString& operator =(const CString& string);
CString operator +(const CString& string) const ;
CString& operator +=(const CString& string);
void print() const ;
private :
char * str;
size_t length;
};
CString& CString::operator =(const CString& string)
{
if (this == &string) // return if the two are the same
return *this ;
delete [] str;
this ->str = new char [string.length+1];
strcpy(this ->str, string.str);
this ->length = string.length;
return *this ;
}
CString CString::operator +(const CString& string) const
{
const int len = this ->length + string.length;
char * temp = new char [len];
temp[0] = '\0' ;
strcat(temp, this ->str);
strcat(temp, string.str);
CString concatenated(temp);
return concatenated;
}
CString& CString::operator +=(const CString& string)
{
this ->length += string.length;
char * temp = new char [this ->length+1];
temp[0] = '\0' ;
strcat(temp, this ->str);
strcat(temp, string.str);
delete [] this ->str;
this ->str = temp;
return *this ;
}
void CString::print() const
{
std::cout << str << std::endl;
return ;
}
int main(void )
{
char string1[] = "Hello, world!" ;
char string2[] = "Goodbye, world!" ;
char * pstr1 = string1;
char * pstr2 = string2;
CString str1(pstr1);
str1.print();
CString str2 = str1;
str2.print();
str1 += str2;
str1.print();
CString str3(pstr2);
str1 = str2 + str3;
str1.print();
pstr1 = NULL;
pstr2 = NULL;
return 0;
}
EDIT: Woah, I just had an epiphany. I could've made the += operator much simpler by writing it like this:
1 2 3 4 5
CString& CString::operator +=(const CString& string)
{
*this = *this + string;
return *this ;
}
Last edited on Jun 13, 2011 at 6:51pm UTC
Jun 13, 2011 at 6:53pm UTC
Oh, while we're at operator+: it leaks memory because it doesn't delete the temp array and it allocates one character less than necessary.
Consider this:
1 2 3 4 5 6
CString CString::operator +(const CString& string) const
{
CString concatenated(*this );
concatenated+=string;
return concatenated;
}
or short:
1 2 3 4
CString CString::operator +(const CString& string) const
{
return CString(*this )+=string;
}
Edit: I see you had a similar idea, but one should generally implement operator+ using operator+=, not the other way round ;)
Last edited on Jun 13, 2011 at 7:08pm UTC
Jun 13, 2011 at 7:37pm UTC
Alright thank you, I switched those two around :)