Manticore -- Custom String Class (Feedback)

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
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
@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
Topic archived. No new replies allowed.