class String
{
private:
size_t len;
char* p;
public:
String(size_t len) : len(len), p(new char[len + 1])
{
p[len] = 0;
}
// ... lots of stuff left out ...
String& operator=(const String &s)
{
if (&s != this)
{
delete[] p;
len = s.len;
p = new char[len + 1];
strcpy(p, s.p);
}
return *this;
}
String operator+(const String& s)
{
String r(len + s.len);
strcpy(r.p, p);
strcpy(r.p + len, s.p);
return r;
}
String& operator+=(const String &s)
{
return *this = *this + s; // <--- can I do this? (no pun intended)
}
// ... lots of stuff left out ...
};
implementing operator+= in terms of operator= and operator+
I'm writing my own String class for educational purposes only, and I was wondering if this is legal C++:
I'm just not sure if it's legal to change *this in a member function. Thanks!
An alternative that might be better is to implement operator+ in terms of operator+=.
And implement the actual functionality in +=.
String operator+(const String& s) { String temp(*this); return temp += s;}
And implement the actual functionality in +=.
Yeah, you can do this. It is perfectly legal to change this in member function -- in fact, that's what member functions are there for.
However, more usual way is to make operator+ non-member and implement it by calling member operator+= which does the actual work.
However, more usual way is to make operator+ non-member and implement it by calling member operator+= which does the actual work.
Quote:Original post by Oxyd
However, more usual way is to make operator+ non-member and implement it by calling member operator+= which does the actual work.
OK, how about this?
class String{// ... String& operator+=(const String &s) { int n = len + s.len; char *q = new char[n + 1]; strcpy(q, p); strcpy(q + len, s.p); len = n; delete[] p; p = q; return *this; }// ...};String operator+(const String &s, const String& t){ String r(s); return r += t;}
Quote:Original post by DevFredQuote:Original post by Oxyd
However, more usual way is to make operator+ non-member and implement it by calling member operator+= which does the actual work.
OK, how about this?
*** Source Snippet Removed ***
That is exactly what I meant. [wink]
I would definitely normally implement operator + via a copy-construction and a call to operator +=. However, in this particular case, doing the reverse as you had originally is simpler and retains the same level of exception safety. So I say, use whichever you prefer in this instance.
Also, if you're interested in exception safety you might like to improve your assignment operator. At the moment, if the 'new' call throws an exception then the String will be left with p pointing to deleted memory, and the destructor of that object will then cause a nasty double-delete bug.
One such way to fix this would be like this:
Now if 'new' throws, then we're "happy as Larry" as the 'this' object doesn't get touched. Note also that because self-assignment also no longer causes a problem, there's no need to explicitly test for and avoid it. Self-assignment is extremely rare in practice so we needn't worry about the fact that it now does actually do copying in this case, and we can instead be pleased with the elimination of the if-statement.
Also, if you're interested in exception safety you might like to improve your assignment operator. At the moment, if the 'new' call throws an exception then the String will be left with p pointing to deleted memory, and the destructor of that object will then cause a nasty double-delete bug.
One such way to fix this would be like this:
String& operator=(const String &s) { char *q = new char[s.len + 1]; strcpy(q, s.p); delete[] p; p = q; len = s.len; return *this; }
Now if 'new' throws, then we're "happy as Larry" as the 'this' object doesn't get touched. Note also that because self-assignment also no longer causes a problem, there's no need to explicitly test for and avoid it. Self-assignment is extremely rare in practice so we needn't worry about the fact that it now does actually do copying in this case, and we can instead be pleased with the elimination of the if-statement.
Quote:Original post by iMalc
I would definitely normally implement operator + via a copy-construction and a call to operator +=. However, in this particular case, doing the reverse as you had originally is simpler and retains the same level of exception safety. So I say, use whichever you prefer in this instance.
Hm, in bothes cases some unnecessary temporaries were created, so I rewrote the class like this (len is now called n):
class String{// ... friend String operator+ (const String& s, const String& t);};String operator+(const String& s, const String& t){ String r(s.n + t.n); strcpy(r.p, s.p); strcpy(r.p + s.n, t.p); return r;}
Thanks about the exception safety hints!
[Edited by - DevFred on May 10, 2008 6:12:46 AM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement