The following code uses the Vec
class, which was implemented
in Chapter 11, in order to implement a string
-like class
called Str
. At the core of the implementation of the
Str
class is a private
data member which is
defined as a vector of characters (i.e. Vec<char>
data
).
Str
class#ifndef STR_H #define STR_H #include <algorithm> #include <cstring> #include <iterator> #include "Vec.h" class Str { // input operator implemented in 12.3.2/216 friend std::istream& operator>>(std::istream&, Str&); public: typedef Vec<char>::size_type size_type; typedef char* iterator; typedef const char* const_iterator; Str() { } Str(size_type n, char c): data(n, c) { } Str(const char* cp) { std::copy(cp, cp + std::strlen(cp), std::back_inserter(data)); } template <class In> Str(In i, In j) { std::copy(i, j, std::back_inserter(data)); } char& operator[](size_type i) { return data[i]; } const char& operator[](size_type i) const { return data[i]; } size_type size() const { return data.size(); } iterator begin() { return data.begin(); } const_iterator begin() const { return data.begin(); } iterator end() { return data.end(); } const_iterator end() const { return data.end(); } Str& operator+=(const Str& s) { std::copy(s.data.begin(), s.data.end(), std::back_inserter(data)); return *this; } private: Vec<char> data; }; // output operator implemented in 12.3.2/216 std::ostream& operator<<(std::ostream&, const Str&); // String concatentation operator. Str operator+(const Str&, const Str&); inline bool operator<(const Str& lhs, const Str& rhs) { return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); } // Other relational operators (e.g. >, <=, >=) can be implemented similarly. inline bool operator==(const Str& lhs, const Str& rhs) { return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin()); } inline bool operator!=(const Str& lhs, const Str& rhs) { return !(lhs == rhs); } #endif
Str
class
#include <cctype> #include <iostream> using std::isspace; #include "Str.h" using std::istream; using std::ostream; Str operator+(const Str& s, const Str& t) { Str r = s; r += t; return r; } ostream& operator<<(ostream& os, const Str& s) { for (Str::size_type i = 0; i != s.size(); ++i) os << s[i]; return os; } istream& operator>>(istream& is, Str& s) { // obliterate existing value(s) s.data.clear(); // read and discard leading whitespace char c; while (is.get(c) && isspace(c)) ; // nothing to do, except testing the condition // if still something to read, do so until next whitespace character if (is) { do // Note that 'data' is private in class 'Str'. // Therefore 'istream& operator>>(istream& is, Str& s)' // must be declared as a friend in the Str class. s.data.push_back(c); while (is.get(c) && !isspace(c)); // if we read whitespace, then put it back on the stream if (is) is.unget(); } return is; }
Last modified: Wed Mar 12 14:04:43 2003