/* string.h * */ #ifndef _MYSTRING_ #define _MYSTRING_ #include #include class MyString { friend bool operator==(const MyString&, const MyString &); friend std::ostream& operator<<(std::ostream&, const MyString &); private: char *str_; int length_; MyString(int); static size_t count; public: MyString(); explicit MyString(char); /* allow implicit conversions, it is useful */ MyString(const char *); /* copy constructor */ MyString(const MyString &); MyString& operator=(const MyString &); ~MyString(); int length() const; int indexOf(char, int = 0) const; bool isSubstring(const MyString &) const; bool isSubstring(const char *) const; MyString& concat(const MyString &); MyString& concat(const char *); void printStr(void) const; static size_t getCount(void); bool operator!(void) const; char& operator[](int); char operator[](int) const; operator char*(); /* outward class conversion into char * */ operator const char*() const; }; bool operator==(const MyString&, const MyString &); bool operator!=(const MyString&, const MyString &); std::ostream& operator<<(std::ostream&, const MyString &); /* it is always good idea to have default ctor to avoid manual init later * for data types that include this class type */ inline MyString::MyString() : str_(new char[1]), length_(0) { str_[0] = '\0'; this->count++; } inline MyString::MyString(char ch) : str_(new char[2]), length_(1) { str_[0] = ch; str_[1] = '\0'; this->count++; } inline int MyString::length() const { return length_; } inline void MyString::printStr(void) const { std::cout << "length: " << length_ << ", value: \"" << str_ << "\""; } inline size_t MyString::getCount(void) { return count; } #endif