// @topic T070m11d07x20 class DString -- copy constructor, destructor, assignment op
// @brief class DString implementation
// DString.cpp
#include "DString.h"
// destructor deallocates previously allocated characters
DString::~DString()
{
delete[] m_array;
}//DString::~DString
// overloaded assignment op implements a "deep" assignment
DString const& DString::operator=(DString const& another)
{
if ( this == &another ) {
// protect against self-assigment
return *this;
}
delete[] m_array;
m_array = nullptr;
m_length = another.m_length;
m_capacity = INITIAL_CAPACITY;
allocate(another.m_capacity);
strcpy(m_array, another.m_array);
return *this;
}//DString::operator=
// copy constructor implements "deep" copy
DString::DString(DString const& another)
:
m_array( nullptr ),
m_length( another.m_length ),
m_capacity( INITIAL_CAPACITY )
{
allocate( another.m_capacity );
strcpy( m_array, another.m_array );
}//DString::DString
// default constructor
DString::DString()
:
m_array( nullptr ),
m_length( 0 ),
m_capacity( INITIAL_CAPACITY )
{
allocate( INITIAL_CAPACITY );
}//DString::DString
// specific constructor
DString::DString( char const* pstr )
:
m_array( nullptr ),
m_length( strlen( pstr ) ),
m_capacity( INITIAL_CAPACITY )
{
allocate( m_length + 1 ); // +1 needed to accommodate zero-terminating char
strcpy( m_array, pstr );
}//DString::DString
// allocate black of characters of the requered capacity
void DString::allocate( size_t capacity )
{
if ( capacity < m_capacity ) return;
char* new_block = new char[ capacity ];
if ( m_array != nullptr ) {
// copy existing content to the new block:
for ( size_t idx = 0; idx < m_length; ++idx ) {
new_block[idx] = m_array[idx];
}
delete[] m_array; // free old block of characters
}
m_array = new_block; // remember new block of characters
m_capacity = capacity;
}//DString::allocate
size_t DString::length() const
{
return m_length;
}//DString::length
size_t DString::capacity() const
{
return m_capacity;
}//DString::capacity
std::ostream& operator<<( std::ostream& cout, DString const& str )
{
for (size_t idx = 0; idx < str.length(); ++idx ) {
cout << str.m_array[idx];
}
return cout;
}//::operator<<
// extract characters from input stream and
// store them in the dynamic string
std::istream& operator>>( std::istream& cin, DString& str )
{
str.m_length = 0;
while ( cin ) {
int ch = cin.get(); // extract next character form cin
if ( ch == '\n' ) break; // new line signals end of input
// before storing next character, check current capacity.
// provide enough space for the ch and zero-terminating char
if ( str.m_length >= str.m_capacity - 1 ) {
// each time the capacity doubles
str.allocate( str.m_capacity * 2 );
}
str.m_array[ str.m_length ] = ch; // store the character
++str.m_length;
}
str.m_array[str.m_length] = '\x00'; // make sure the content is zero-terminated
return cin;
}//::operator>>