>but I'd really like to make my own
That's fine, a string class is a good exercise for many levels of experience. But this particular functionality is silly, why would you want to concatenate two literal strings when this occurs anyway?
MyString = "Hello " " World, " " how are we" " today?";
This gives you the same result. The standard string class doesn't implement this functionality because it isn't needed. If you are going to use two string literals in a row then why not make them into one?
MyString = "Hello World, how are we today?";
When adding features to your class, consider long and hard whether they are actually needed or not. A useful string class really doesn't need that much, here is one I wrote recently. I split off the substring functions into another class, the end result is a surprisingly compact string class. This is because I didn't overload it with unnecessary or not often used features. Sure, it isn't a spectacular show of programming skill, but there's little point in writing a monolithic class that nobody understands:
Code:
namespace pre
{
/////////////////////////////////////
//
// pre::string class
// Basic string functionality
// by Julienne Walker
//
/////////////////////////////////////
class string
{
public:
// Public type definitions
typedef char *iterator;
typedef const char *const_iterator;
typedef size_t size_type;
public:
// Object constructors and destructor
string();
string ( size_type, char );
string ( const string& );
string ( const char * );
string ( const_iterator, const_iterator );
~string();
public:
// Subscript access operators
char& operator[] ( size_type );
const char& operator[] ( size_type ) const;
public:
// Assignment operators
string& operator= ( const string& );
string& operator= ( const char * );
public:
// Concatenation assignment operators
string& operator+= ( const string& );
string& operator+= ( const char * );
public:
// Concatenation operators
string operator+ ( const string& );
string operator+ ( const char * );
public:
// Public user interface
void push_back ( const char& );
void clear();
void clear_all();
size_type size() const;
size_type length() const;
const char *c_str();
const char *data();
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
bool compare ( const string& ) const;
bool compare ( const char * ) const;
private:
// Memory handling functions
void build_mem();
void build_mem ( size_type, const char& );
void build_mem ( const_iterator, const_iterator );
void unbuild_mem();
void resize();
private:
// Memory handling variables
iterator str_data; // Beginning of string
iterator str_end; // End of string
iterator mem_end; // End of memory allocated to string
std::allocator<char> alloc;
};
}
// Global string operators and functions
std::istream& operator>> ( std::istream&, pre::string& );
std::ostream& operator<< ( std::ostream&, pre::string );
std::istream& getline ( std::istream&, pre::string& );
bool operator== ( const pre::string&, const char * );
bool operator== ( const pre::string&, const pre::string& );
bool operator!= ( const pre::string&, const char * );
bool operator!= ( const pre::string&, const pre::string& );
-Prelude