I wanted to create a basic String
class that will hold a CString
and have:
- constructor, destructor, copy constructor
- assignment operator (both from String and CString)
<<
and>>
operators to stream withcout
andcin
==
,<
and>
operators to compareString
s[ ]
operator to access a certainchar
in a stringLen()
function to get the length of the stringCStr()
to access the C string in theString
class
This is really a part of my baby steps in C++, so any feedback about style, design and coding will be appreciated. Attached are both the header file (the interface, as I learned it is called) and the cpp file:
/*
string.h
Written by me on Jan 27, 2015
*/
#include <iostream>
using namespace std;
namespace exercises
{
class String;
ostream& operator<<(ostream&, const String&);
istream& operator>>(istream&, String&);
class String
{
public:
explicit String(const char* str_="");
~String();
String(String const &oStr_);
String& operator=(const String& oStr_);
String& operator=(const char* oStr_);
bool operator==(const String& oStr_)const;
bool operator<(const String& oStr_)const;
bool operator>(const String& oStr_)const;
char operator[](std::size_t)const;
char& operator[](std::size_t);
const std::size_t Len()const;
const char* CStr()const;
private:
char* m_str;
};
} //namespace exercises
/* string.cpp
Written by me on Jan 27, 2015
*/
#include <iostream>
#include <cstring>
#include "string.h"
using namespace std;
namespace exercises
{
static int BUFFSIZE = 256; // buffer size limit for streams
// ---------- C~=tor funcs ----------
String::String(const char* str_)
{
m_str = new char[strlen(str_)+1];
strcpy(m_str, str_);
}
String::~String()
{
delete[] m_str;
}
String::String(String const &oStr_)
{
m_str = new char[strlen(oStr_.m_str)+1];
strcpy(m_str, oStr_.m_str);
}
String& String::operator=(const String& oStr_)
{
char* newString = new char[strlen(oStr_.m_str)+1];
delete[] m_str;
m_str = newString;
strcpy(m_str, oStr_.m_str);
return *this;
}
String& String::operator=(const char* oCStr_)
{
char* newCStr = new char[strlen(oCStr_)+1];
delete[] m_str;
m_str = newCStr;
strcpy(m_str, oCStr_);
return *this;
}
// ---------- global funcs ----------
ostream& operator<<(ostream& os_, const String& str_)
{
return os_ << str_.CStr();
}
istream& operator>>(istream& is_, String& str_)
{
char* newCStr = new char[BUFFSIZE];
is_.get (newCStr,BUFFSIZE);
str_ = newCStr;
delete[] newCStr;
return is_;
}
// ---------- interface funcs ----------
bool String::operator==(const String& oStr_)const
{
return !strcmp(m_str, oStr_.m_str);
}
bool String::operator<(const String& oStr_)const
{
return strcmp(m_str, oStr_.m_str) < 0;
}
bool String::operator>(const String& oStr_)const
{
return strcmp(m_str, oStr_.m_str) > 0;
}
char String::operator[](std::size_t i)const
{
return *(m_str+i);
}
char& String::operator[](std::size_t i)
{
return *(m_str+i);
}
const std::size_t String::Len()const
{
return strlen(m_str);
}
const char* String::CStr()const
{
return const_cast<const char*>(m_str);
}
} // namespace exercises