Feb 27, 2016 at 11:27pm UTC
Hello,
A couple of weeks ago I decided to test my knowledge I have gathered thus far and see if I could write my own string class. From what I have gathered from reading various websites is that writing your own string class in general is a bad idea. Manticore is NOT going to replace the already provided std::string class. It was a small project to test my knowledge.
I appreciate the feedback coming from more experienced coders. That is the primary reason why I decided to post my class here. I would like to apologize in advance if this is completely wrong.
For those who want to see it in action; http://prntscr.com/a8sy4h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
#ifndef _MANTICORE__H
#define _MANTICORE__H
#pragma once
#include <Windows.h>
class Manticore {
private :
char m_OoB;
char * m_Data;
size_t m_Length;
size_t m_BufferSize;
private :
unsigned char srealloc(size_t);
public :
Manticore ( const char * );
Manticore ( const Manticore& );
~Manticore ( );
char & operator [] ( size_t );
void operator += ( const char * );
void operator += ( const Manticore& );
void upper ( void );
void lower ( void );
void replace ( const char , const char );
void reverse ( void );
void append ( const char * );
void trim ( void );
size_t length ( void ) const ;
size_t size ( void ) const ;
const char * c_str ( void ) const ;
};
#endif
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
#include "stringmgr.h"
Manticore::Manticore(const char * pszData) {
if ( !pszData || pszData[0] == '\0' )
return ; // FIX LATER
size_t length = strlen ( pszData );
this ->m_Data = new char [ length + 1 ]();
this ->m_BufferSize = (length + 1);
this ->m_Length = length;
this ->m_OoB = 0;
if ( !m_Data ) return ; // FIX LATER
memcpy( m_Data, pszData, length );
}
Manticore::Manticore(const Manticore& mCore) {
this ->m_Data = new char [ mCore.m_BufferSize ]();
memcpy( this ->m_Data, mCore.m_Data, mCore.m_Length );
this ->m_BufferSize = mCore.m_BufferSize;
this ->m_Length = mCore.m_Length;
this ->m_OoB = mCore.m_OoB;
}
Manticore::~Manticore() {
delete [] m_Data;
};
unsigned char Manticore::srealloc(size_t nsize) {
if ( !m_Data )
return 1; // FIX LATER
char * buffer = new char [ nsize + 1 ]();
if ( !buffer )
return 2; // FIX LATER
memcpy ( buffer, m_Data, m_Length + 1 );
delete [] m_Data;
m_Data = buffer;
m_BufferSize = ( nsize + 1 );
return 0; // FIX LATER
}
char & Manticore::operator [](size_t index) {
return ( ( index < 0 || index > this ->m_Length ) ? this ->m_OoB : this ->m_Data [ index ] );
}
void Manticore::operator +=(const char * pszData) {
this ->append ( pszData );
}
void Manticore::operator +=(const Manticore& mCore) {
this ->append ( mCore.m_Data );
}
void Manticore::upper(void ) {
char * data = this ->m_Data;
unsigned int pos = 0;
while ( pos < this ->m_Length ) {
if ( *(data + pos ) >= 'a' && *( data + pos ) <= 'z' )
*( data + pos ) -= ( 'a' - 'A' );
pos++;
}
}
void Manticore::lower(void ) {
char * data = this ->m_Data;
unsigned int pos = 0;
while ( pos < this ->m_Length ) {
if ( *( data + pos ) >= 'A' && *( data + pos ) <= 'Z' )
*( data + pos ) += ( 'a' - 'A' );
pos++;
}
}
void Manticore::replace(const char dst, const char src) {
char * data = this ->m_Data;
unsigned int pos = 0;
while ( pos < this ->m_Length ) {
if ( *( data + pos ) == dst )
*( data + pos ) = src;
pos++;
}
}
void Manticore::reverse(void ) {
char * data = this ->m_Data;
char * back = ( this ->m_Data + ( this ->m_Length - 1 ) );
char buffer = 0;
while ( back > data ) {
buffer = *data;
*data = *back;
*back = buffer;
data++; back--;
}
}
void Manticore::append(const char * pszData) {
size_t src_len = strlen ( pszData );
size_t available = ( ( this ->m_BufferSize - 1 ) - this ->m_Length );
if ( available < src_len || available == src_len )
this ->srealloc( ( this ->m_Length + src_len ) );
memcpy(this ->m_Data + m_Length, pszData, src_len );
this ->m_Length += src_len;
}
void Manticore::trim(void ) {
char * front = this ->m_Data;
char * back = ( this ->m_Data + this ->m_Length ) - 1;
size_t src_len = this ->m_Length;
while (*front && isspace((int )*front)) front++;
while (src_len && *back && isspace((int )*back)) { src_len--; back--; }
size_t new_size = ( back - front ) + 1;
char * buffer = new char [ new_size + 1 ]();
memcpy(buffer, front, new_size);
delete [] this ->m_Data;
this ->m_Data = buffer;
this ->m_BufferSize = ( new_size + 1 );
this ->m_Length = new_size;
}
size_t Manticore::length(void ) const {
return this ->m_Length;
}
size_t Manticore::size(void ) const {
return this ->m_BufferSize;
}
const char * Manticore::c_str(void ) const {
return this ->m_Data;
}
Update 1; Class updated with the feedback provided by kbw
Last edited on Feb 28, 2016 at 10:43am UTC
Feb 27, 2016 at 11:46pm UTC
Very good. I do have a few comments.
You need to implements the assignment operator too. operator =
What's the deal with MAX_BUFFER_SIZE? You don't actually have a maximum as you're getting your memory from the heap.
Concentrate on interface. How is someone going to use this object? Someone who uses a string who doesn't care about that srealloc thing or that xor madness. Whatever it is, it doesn't belong in the public interface.
c_str() should be a const member.
The member data should be private. No one should have access. Extending stuff is a matter of design, it can't be done properly by accident or convenience.
I hope you can now see the value of exceptions. It's the only way to handle some of those errors that you don't know what to do with.
Last edited on Feb 27, 2016 at 11:48pm UTC
Feb 28, 2016 at 10:38am UTC
@kbw,
Thank you very much for the feedback. I have re-worked the class a little bit. operator =
will be added later today.
~ Lonely One
Last edited on Feb 28, 2016 at 10:42am UTC