@larsmans already answered your precise question, so I'll actually digress: This is some crappy code!
The issue here is 3-fold:
- You just duplicated the code of the copy constructor (somewhat)
strcpy
could be better replaced by strncpy
, which does some bound checking
- It is not exception safe
1) and 2) are more stylistic than anything, but the 3) is a big concern
EDIT: as pointed out by @Jerry Coffin, this does not protected against self-assignment. That is if sobj
and _string
point to the same array of characters, you're in big troubles. The easy solution at the end of this post also covers this situation.
Not exception safe
Let's have a look at a portion of the code, namely, the else
part:
_size = strlen( sobj );
delete[] _string;
_string = new char[ _size + 1 ];
strcpy( _string, sobj );
What happens if, for some reason, new
throws ?
_size
has the value of the new string
_string
points to the old pointer... which has been freed
Therefore not only the object is left in an unusable state (half of its data from the new object, half from the old), but it cannot even be destroyed (unless the destructor leaks... ?)
Adding exception safety, the hard way
_size = strlen( sobj );
delete[] _string;
try {
_string = new char[ _size + 1 ];
} catch(...) {
_size = 0; _string = 0;
throw;
}
strcpy( _string, sobj );
Okay, it's really bottom-line, but it brings us the Basic Exception Guarantee: no functional guarantee, but a guarantee that the code is technically correct (no crash, no leak).
Adding exception safety, the easy way: The Copy-And-Swap idiom
Find a more complete description at: What is the copy-and-swap idiom ?
void swap(String& lhs, String& rhs) {
using std::swap;
swap(lhs._size, rhs._size);
swap(lhs._string, rhs._string);
}
String& String::operator=(String other) { // pass-by-value
swap(*this, other);
return *this;
}
How does it work ?
- we reuse the copy constructor for the actual copy
- we reuse the swap function for exchanging values
- we reuse the destructor for the clean-up
And it's even better than the previous version too, for now we have the Strong Exception Guarantee: it's transactional, thus if it fails, the string we assigned to is unchanged (as if nothing had happened).
More about Exception Guarantees.
I am a bit daunted that a C++ tutorial would promote such dubious code, pray tell me it's an example of what not to do :/