Your class should keep track of two things: the string length (so that you don't have to calculate it every time) and the amount of allocated memory. This is a huge opportunity for optimization. Your current class is very inefficient because it ALWAYS reallocates the memory. An efficient string class keeps track of how much memory it has and only reallocates if it needs more memory. This means for example when you assign a small string to an object that previously held a large string, you don't need to reallocate.
Then you need an allocation strategy for building strings. For example, if a user keeps adding a single character to a string (like in a loop) and you have a "allocate-only-what-you-need" strategy, you have to allocate every loop iteration. The most common strategy is "double-when-out": whenever you run out of memory, allocate twice as much as currently held.

The MS STL implementation of std::string also contains an automatically allocated area for 16 characters in order to store small strings quickly. However, this approach makes it complicated.