Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Soulstorm

macrumors 68000
Original poster
Feb 1, 2005
1,887
1
I am trying to recreate a class that will simulate an STL string. So far, I have had no problems. Here is my class, named stash
stash.h
Code:
#ifndef STASH_H
#define STASH_H
#include <iostream>
#include <string>

#define MasterStringBuild 30
#define MasterStringBuildString "Beta Build"

#define next currentStorage - currentSize
#define STDstring std::string
#define STDostream std::ostream
#define STDistream std::istream

//TO BE EXTENSIVELY TESTED AND REVISED BEFORE RELEASE!!!!!!!!!!

class stash;
typedef stash MasterString; //New Definition for the Stash

class stash{
	char *ch;
	unsigned int currentSize;		//position of the last character
	unsigned int currentStorage;		//size of the entire array
	//unsigned int next;
public:
	
	//constructors
	stash();
	stash(unsigned int startSize);
	stash(char *p);
	stash(stash &other);	//copy constructor
	~stash();
	
	//main functions
	void show();
	void inflate();
	void add(char p);
	void insertString(const char *p);
	void insertSTLString(STDstring s);
	char* returnAsString();
	void resetStash();
	
	//information getters
	char returnCharacterAtPosition(unsigned int i);
	int returnCurrentSize(){return currentSize;}
	int returnCurrentStorage(){return currentStorage;}
	STDstring returnAsSTLString();
	//int returnNext(){return next;}
	char* returnPointerToCh(){return ch;}
	
	//overloaded operators
	void operator+(const char *p);
	void operator+(stash& s);
	void operator+(char s);
	
	void operator=(const char *p);
	void operator=(stash s);
	void operator=(STDstring &s);
	
	char operator[](unsigned int i);
	
	bool operator==(stash s);
	bool operator==(const char *p);
	bool operator==(STDstring s);
	
	//miscellaneous editing
	void appendString(stash &s);
	void appendString(char *CStyleString);
	void appendString(STDstring s);
	
	void insertStringAtPosition(stash &s, unsigned int pos);
	void insertStringAtPosition(char *CStyleString, unsigned int pos);
	void insertStringAtPosition(STDstring s, unsigned int pos);
	
	STDstring returnRangeAsSTLString(unsigned int startPos, unsigned int endPos);
	stash returnRangeAsStash(unsigned int startPos, unsigned int endPos);
	
	void deleteCharactersBetweenIndex(unsigned int startIndex, unsigned int endIndex);
	
	friend STDostream &operator<<(STDostream &stream, stash &ob);
	friend STDistream &operator>>(STDistream &stream, stash &ob);
	
	//build informative functions
	int returnCurrentMasterStringBuild();
};

#endif
and stash.cpp:
Code:
#include <iostream>
#include "stash.h"
#include <string> 

using std::cout;

int gIncrement = 8; //Number of bytes to add each time the class is expanded
					//Smaller numbers guarantee less memory consuption, but
					//also a small performance hit.

//**constructors and destructors
stash::stash(){
	ch = 0; //allocate zero to initialize the 'ch' pointer'
	resetStash();
}

stash::stash(unsigned int startSize){
	ch = new char [startSize];
	currentSize = 0;
	currentStorage = startSize;
	//next = currentStorage - currentSize;
}

stash::~stash(){
	delete [] ch;
	cout << "Freeing storage\n"; //**for debugging purposes only
}

stash::stash(char *p){
	ch = 0;
	resetStash();
	insertString(p);
}

stash::stash(stash &other){
	ch = 0;
	resetStash();
	insertString(other.returnPointerToCh());
}

//*******

//Show the elements of the class
void stash::show(){
	cout << "currentStorage: " << currentStorage << "\n";
	cout << "current size: " << currentSize << "\n";
	cout << "Next: " << next << "\n";
	for(int i=0; i<currentSize; i++)
		cout << ch[i];
	cout << "\n";
}

//--Increase the stash's size to hold more chars.
void stash::inflate(){
	int i;
	char *temp = new char [currentSize + gIncrement];
	for(i=0; i<currentSize; i++)
		temp[i] = ch[i];
	delete [] ch;
	ch = temp;
	currentStorage = currentStorage + gIncrement;
}

//--add a character to the stash and resize it according
//--to space needed
void stash::add(char p){
	if(next == 0)
		inflate();
	ch[currentSize] = p;
	++currentSize;
	//next = currentStorage - currentSize;
}

//--reset the stash
void stash::resetStash(){
	if(ch)
		delete [] ch;
	ch = new char [gIncrement];
	currentSize = 0;
	currentStorage = gIncrement;
	//next =  gIncrement - currentSize;
}

//--insert an entire string into the stash
void stash::insertString(const char *p){
	int i;
	for(i=0; p[i]; i++){
		add(p[i]);
	}
}

//--Insert an STL string into the MasterString class
void stash::insertSTLString(STDstring s){
	int i;
	resetStash();
	for(i=0; i<s.size(); i++)
		add(s[i]);
}

//--make the chars a string
char* stash::returnAsString(){
	add('\0');
	//next--; 
	currentSize--;
	return ch;
}

//--return the masterstring as an STL string
STDstring stash::returnAsSTLString(){
	return STDstring(returnAsString());
}

//--add more chars into the string;
void stash::operator+(const char *p){
	insertString(p);
}

//--experimental: add 2 MasterStrings
//--add more chars into the string;
void stash::operator+(stash &s){
	insertString(s.returnAsString());
}

void stash::operator+(char s){
	add(s);
}

//--Return a character at a specified position
//--Return NULL if a character doesn't exist at the
//--requested position
char stash::returnCharacterAtPosition(unsigned int i){
	if(i>currentSize)
		return NULL;
	return ch[i];
}

//--clear the stash and hold a new string
void stash::operator=(const char *p){
	resetStash();
	insertString(p);
}

//--make a string hold exactly what the other holds!!!
void stash::operator=(stash s){
	int i;
	delete [] ch; //delete before assignment
	char *temp = new char [s.returnCurrentSize()];
	for(i=0; i<s.returnCurrentSize(); i++){
		temp[i] = s.returnCharacterAtPosition(i);
	}
	//next = s.returnNext();
	currentStorage = s.returnCurrentStorage();
	currentSize = s.returnCurrentSize();
	ch = temp;
}

//--make the MasterString hold an STL string
//--with the '=' operator
void stash::operator=(STDstring &s){
	insertSTLString(s);
}

//--Return a character at a specified integer position
char stash::operator[](unsigned int i){
	return returnCharacterAtPosition(i);
}

//--Compare two stashes together
bool stash::operator==(stash s){
	if(strcmp(s.returnPointerToCh(),ch))
		return 0;
	return 1;
}

//--Compare a stash with a const char
bool stash::operator==(const char *p){
	if(strcmp(p,ch))
		return 0;
	return 1;
}

//--Compare a stash with an STL string
bool stash::operator==(STDstring s){
	if(strcmp(s.c_str(),ch))
	   return 0;
	return 1;
}

//--Overloaded appendString function
//--TO BE TESTED!
void stash::appendString(stash &s){
	int i;
	for(i=0; i<s.returnCurrentSize(); i++){
		add(s[i]);
	}
}

void stash::appendString(char *CStyleString){
	int i;
	for(i=0; i<strlen(CStyleString); i++){
		add(CStyleString[i]);
	}
}

void stash::appendString(STDstring s){
	int i;
	for(i=0; i<s.size(); i++){
		add(s[i]);
	}
}
//**

//--Insert Strings At Positions:
void stash::insertStringAtPosition(char *CStyleString, unsigned int pos){
	STDstring result(CStyleString);
	insertStringAtPosition(result,pos);
}

void stash::insertStringAtPosition(stash &s, unsigned int pos){
	insertStringAtPosition(s.returnAsSTLString(),pos);
}

void stash::insertStringAtPosition(STDstring s, unsigned int pos){
	STDstring result;
	int i;
	for(i=0; i<=pos; i++){
		result = result + ch[i];
	}
	for (i=0; i<s.size(); i++) {
		result = result + s[i];
	}
	for (i=pos+1; i<(returnCurrentSize()); i++) {
		result = result + ch[i];
	}
	*this = result; //assign the new masterstring to self
	
}
//**

//--Return a range of characters inside the MasterString
//--as an STDstring
STDstring stash::returnRangeAsSTLString(unsigned int startPos, unsigned int endPos){
	STDstring result;
	int i;
	for(i=startPos; i<endPos; i++){
		result = result + ch[i];
	}
	return result;
}

//THIS FUNCTION HAS PROBLEMS!!!!!
stash stash::returnRangeAsStash(unsigned int startPos, unsigned int endPos){
	stash result;
	int i;
	for(i=startPos; i<endPos; i++){
		result + ch[i];
	}
	cout << result;
	return result;
}

//--Delete characters inside the MasterString that are
//--between a given index
void stash::deleteCharactersBetweenIndex(unsigned int startIndex, unsigned int endIndex){
	STDstring result;
	int i;
	for(i=0; i<startIndex; i++){
		result = result + ch[i];
	}
	for(i=endIndex; i<currentSize; i++){
		result = result + ch[i];
	}
	insertSTLString(result);
}



/***************************Informative Functions*****************************/
int returnCurrentMasterStringBuild(){
	return MasterStringBuild;
}

/***************************Friendly functions********************************/
//--Overloaded operator <<
STDostream &operator<<(STDostream &stream, stash &ob){
	int i;
	for(i=0; i<ob.currentSize; i++){
		stream << ob.returnCharacterAtPosition(i);
	}
	return stream;
}

//--Experimental: overloaded operator >>
STDistream &operator>>(STDistream &stream, stash &ob){
	STDstring s;
	getline(stream,s);
	ob.insertSTLString(s);
	return stream;
}

try using this main, and you will get errors:
Code:
#include <iostream>
#include "stash.h"
using namespace std;

int main(){
	MasterString s("0123456789");
	s.deleteCharactersBetweenIndex(3,8);
	MasterString k;
	
	k = s.returnRangeAsStash(3,6);
	
	cout << k;
	return 0;
}
The error I get is this:
Code:
main.cpp:10: error:   initializing argument 1 of 'void stash::operator=(stash)'
main.cpp:10: error: no matching function for call to 'stash::stash(stash)'
stash.h:36: note:                 stash::stash(unsigned int)
stash.h:37: note:                 stash::stash(char*)
stash.h:38: note: candidates are: stash::stash(stash&)
Why is that? Why am I getting these errors?
 

Soulstorm

macrumors 68000
Original poster
Feb 1, 2005
1,887
1
Also, can anyone tell me why the Compiler doesn't let me change my copy constructor and put 'const stash& other' as an argument? It only lets me put 'stash& other' as an argument because if I put the other one, it gets me an error about
Code:
stash.cpp:48: error: passing 'const stash' as 'this' argument of 'char* stash::returnPointerToCh()' discards qualifiers
at this function:
Code:
stash::stash(const stash &other){
	ch = 0;
	resetStash();
	insertString(other.returnPointerToCh());
}
 

slooksterPSV

macrumors 68040
Apr 17, 2004
3,544
306
Nowheresville
906Freeing storage
0xbffff97c

That's the output I got when I changed these lines:
Ok now understand this, there is no call for stash::stash(stash) only a reference (right?) to stash::stash(stash &)

So you need to return Pointers, think about when you do k = s.return...
that's using the constructor stash(stash) which does not exist
If you do k = s->return...
it works. Here's the updated code:

Code:
//main.cpp
#include <iostream>
#include "stash.h"

using namespace std;

int main(){
	//char* number = "0123456789";
	MasterString *s = new MasterString("1234567890");
	s->deleteCharactersBetweenIndex(3,8);
	MasterString *k;
	
	k = s->returnRangeAsStash(3, 6);
	
	cout << k << endl;
	return 0;
}

Stash.h
Code:
//stash.h
#ifndef STASH_H
#define STASH_H
#include <iostream>
#include <string>

#define MasterStringBuild 30
#define MasterStringBuildString "Beta Build"

#define next currentStorage - currentSize
#define STDstring std::string
#define STDostream std::ostream
#define STDistream std::istream

//TO BE EXTENSIVELY TESTED AND REVISED BEFORE RELEASE!!!!!!!!!!

class stash;
typedef stash MasterString; //New Definition for the Stash

class stash{
	char *ch;
	unsigned int currentSize;		//position of the last character
	unsigned int currentStorage;		//size of the entire array
	//unsigned int next;
public:
	
	//constructors
	stash();
	stash(unsigned int startSize);
	stash(char *p);
	stash(stash &other);	//copy constructor
	
	~stash();
	
	//main functions
	void show();
	void inflate();
	void add(char p);
	void insertString(const char *p);
	void insertSTLString(STDstring s);
	char* returnAsString();
	void resetStash();
	
	//information getters
	char returnCharacterAtPosition(unsigned int i);
	int returnCurrentSize(){return currentSize;}
	int returnCurrentStorage(){return currentStorage;}
	STDstring returnAsSTLString();
	//int returnNext(){return next;}
	char* returnPointerToCh(){return ch;}
	
	//overloaded operators
	void operator+(const char *p);
	void operator+(stash& s);
	void operator+(char s);
	
	void operator=(const char *p);
	void operator=(stash s);
	void operator=(STDstring &s);
	
	char operator[](unsigned int i);
	
	bool operator==(stash s);
	bool operator==(const char *p);
	bool operator==(STDstring s);
	
	//miscellaneous editing
	void appendString(stash &s);
	void appendString(char *CStyleString);
	void appendString(STDstring s);
	
	void insertStringAtPosition(stash &s, unsigned int pos);
	void insertStringAtPosition(char *CStyleString, unsigned int pos);
	void insertStringAtPosition(STDstring s, unsigned int pos);
	
	STDstring returnRangeAsSTLString(unsigned int startPos, unsigned int endPos);
	stash *returnRangeAsStash(unsigned int startPos, unsigned int endPos);
	
	void deleteCharactersBetweenIndex(unsigned int startIndex, unsigned int endIndex);
	
	friend STDostream &operator<<(STDostream &stream, stash &ob);
	friend STDistream &operator>>(STDistream &stream, stash &ob);
	
	//build informative functions
	int returnCurrentMasterStringBuild();
};

#endif

stash.cpp
Code:
//stash.cpp
#include <iostream>
#include "stash.h"
#include <string> 

using std::cout;

int gIncrement = 8; //Number of bytes to add each time the class is expanded
					//Smaller numbers guarantee less memory consuption, but
					//also a small performance hit.

//**constructors and destructors
stash::stash(){
	ch = 0; //allocate zero to initialize the 'ch' pointer'
	resetStash();
}

stash::stash(unsigned int startSize){
	ch = new char [startSize];
	currentSize = 0;
	currentStorage = startSize;
	//next = currentStorage - currentSize;
}

stash::~stash(){
	delete [] ch;
	cout << "Freeing storage\n"; //**for debugging purposes only
}

stash::stash(char *p){
	ch = 0;
	resetStash();
	insertString(p);
}

stash::stash(stash &other){
	ch = 0;
	resetStash();
	insertString(other.returnPointerToCh());
}

//*******

//Show the elements of the class
void stash::show(){
	cout << "currentStorage: " << currentStorage << "\n";
	cout << "current size: " << currentSize << "\n";
	cout << "Next: " << next << "\n";
	for(int i=0; i<currentSize; i++)
		cout << ch[i];
	cout << "\n";
}

//--Increase the stash's size to hold more chars.
void stash::inflate(){
	int i;
	char *temp = new char [currentSize + gIncrement];
	for(i=0; i<currentSize; i++)
		temp[i] = ch[i];
	delete [] ch;
	ch = temp;
	currentStorage = currentStorage + gIncrement;
}

//--add a character to the stash and resize it according
//--to space needed
void stash::add(char p){
	if(next == 0)
		inflate();
	ch[currentSize] = p;
	++currentSize;
	//next = currentStorage - currentSize;
}

//--reset the stash
void stash::resetStash(){
	if(ch)
		delete [] ch;
	ch = new char [gIncrement];
	currentSize = 0;
	currentStorage = gIncrement;
	//next =  gIncrement - currentSize;
}

//--insert an entire string into the stash
void stash::insertString(const char *p){
	int i;
	for(i=0; p[i]; i++){
		add(p[i]);
	}
}

//--Insert an STL string into the MasterString class
void stash::insertSTLString(STDstring s){
	int i;
	resetStash();
	for(i=0; i<s.size(); i++)
		add(s[i]);
}

//--make the chars a string
char* stash::returnAsString(){
	add('\0');
	//next--; 
	currentSize--;
	return ch;
}

//--return the masterstring as an STL string
STDstring stash::returnAsSTLString(){
	return STDstring(returnAsString());
}

//--add more chars into the string;
void stash::operator+(const char *p){
	insertString(p);
}

//--experimental: add 2 MasterStrings
//--add more chars into the string;
void stash::operator+(stash &s){
	insertString(s.returnAsString());
}

void stash::operator+(char s){
	add(s);
}

//--Return a character at a specified position
//--Return NULL if a character doesn't exist at the
//--requested position
char stash::returnCharacterAtPosition(unsigned int i){
	if(i>currentSize)
		return NULL;
	return ch[i];
}

//--clear the stash and hold a new string
void stash::operator=(const char *p){
	resetStash();
	insertString(p);
}

//--make a string hold exactly what the other holds!!!
void stash::operator=(stash s){
	int i;
	delete [] ch; //delete before assignment
	char *temp = new char [s.returnCurrentSize()];
	for(i=0; i<s.returnCurrentSize(); i++){
		temp[i] = s.returnCharacterAtPosition(i);
	}
	//next = s.returnNext();
	currentStorage = s.returnCurrentStorage();
	currentSize = s.returnCurrentSize();
	ch = temp;
}

//--make the MasterString hold an STL string
//--with the '=' operator
void stash::operator=(STDstring &s){
	insertSTLString(s);
}

//--Return a character at a specified integer position
char stash::operator[](unsigned int i){
	return returnCharacterAtPosition(i);
}

//--Compare two stashes together
bool stash::operator==(stash s){
	if(strcmp(s.returnPointerToCh(),ch))
		return 0;
	return 1;
}

//--Compare a stash with a const char
bool stash::operator==(const char *p){
	if(strcmp(p,ch))
		return 0;
	return 1;
}

//--Compare a stash with an STL string
bool stash::operator==(STDstring s){
	if(strcmp(s.c_str(),ch))
	   return 0;
	return 1;
}

//--Overloaded appendString function
//--TO BE TESTED!
void stash::appendString(stash &s){
	int i;
	for(i=0; i<s.returnCurrentSize(); i++){
		add(s[i]);
	}
}

void stash::appendString(char *CStyleString){
	int i;
	for(i=0; i<strlen(CStyleString); i++){
		add(CStyleString[i]);
	}
}

void stash::appendString(STDstring s){
	int i;
	for(i=0; i<s.size(); i++){
		add(s[i]);
	}
}
//**

//--Insert Strings At Positions:
void stash::insertStringAtPosition(char *CStyleString, unsigned int pos){
	STDstring result(CStyleString);
	insertStringAtPosition(result,pos);
}

void stash::insertStringAtPosition(stash &s, unsigned int pos){
	insertStringAtPosition(s.returnAsSTLString(),pos);
}

void stash::insertStringAtPosition(STDstring s, unsigned int pos){
	STDstring result;
	int i;
	for(i=0; i<=pos; i++){
		result = result + ch[i];
	}
	for (i=0; i<s.size(); i++) {
		result = result + s[i];
	}
	for (i=pos+1; i<(returnCurrentSize()); i++) {
		result = result + ch[i];
	}
	*this = result; //assign the new masterstring to self
	
}
//**

//--Return a range of characters inside the MasterString
//--as an STDstring
STDstring stash::returnRangeAsSTLString(unsigned int startPos, unsigned int endPos){
	STDstring result;
	int i;
	for(i=startPos; i<endPos; i++){
		result = result + ch[i];
	}
	return result;
}

//THIS FUNCTION HAS PROBLEMS!!!!!
stash *stash::returnRangeAsStash(unsigned int startPos, unsigned int endPos){
	stash result;
	int i;
	for(i=startPos; i<endPos; i++){
		result + ch[i];
	}
	cout << result;
	return &result;
}

//--Delete characters inside the MasterString that are
//--between a given index
void stash::deleteCharactersBetweenIndex(unsigned int startIndex, unsigned int endIndex){
	STDstring result;
	int i;
	for(i=0; i<startIndex; i++){
		result = result + ch[i];
	}
	for(i=endIndex; i<currentSize; i++){
		result = result + ch[i];
	}
	insertSTLString(result);
}



/***************************Informative Functions*****************************/
int returnCurrentMasterStringBuild(){
	return MasterStringBuild;
}

/***************************Friendly functions********************************/
//--Overloaded operator <<
STDostream &operator<<(STDostream &stream, stash &ob){
	int i;
	for(i=0; i<ob.currentSize; i++){
		stream << ob.returnCharacterAtPosition(i);
	}
	return stream;
}

//--Experimental: overloaded operator >>
STDistream &operator>>(STDistream &stream, stash &ob){
	STDstring s;
	getline(stream,s);
	ob.insertSTLString(s);
	return stream;
}
[/code]
 

slooksterPSV

macrumors 68040
Apr 17, 2004
3,544
306
Nowheresville
As for your second to comment/q?
const stash &other
you can add that only if you add to the function:
stash temp = other;
...
change
other.return....
to
temp.return...
 

Soulstorm

macrumors 68000
Original poster
Feb 1, 2005
1,887
1
slooksterPSV said:
As for your second to comment/q?
const stash &other
you can add that only if you add to the function:
stash temp = other;
...
change
other.return....
to
temp.return...
This brings up the debugger because a runtime error has occured. In the debugger I see that all temp and s variables are out of scope. why? this is the new copy-constructor
Code:
stash::stash(const stash& other){
	stash temp = other;
	ch = 0;
	resetStash();
	insertString(temp.returnPointerToCh());
}
 

slooksterPSV

macrumors 68040
Apr 17, 2004
3,544
306
Nowheresville
Soulstorm said:
This brings up the debugger because a runtime error has occured. In the debugger I see that all temp and s variables are out of scope. why? this is the new copy-constructor
Code:
stash::stash(const stash& other){
	stash temp = other;
	ch = 0;
	resetStash();
	insertString(temp.returnPointerToCh());
}
I don't know, it works for me. Is it being compiled as GCC or G++, it needs to be G++
 

Gil Bates

macrumors newbie
Jun 16, 2006
18
0
Frozen Wasteland
I think the problem in your 1st post is that you don't have a copy constructor:
Code:
stash(const stash &) // (note "const")
I don't think stash(stash &) is a copy constructor.


The problems in your 2nd post is that returnPointerToCh() is called for a "const" object while returnPointerToCh() is not "const". You need:
Code:
char * returnPointerToCh() const { ... };
This will declare that the function will not modify itself.

Furthermore, you probably should declare it as:
Code:
const char * returnPointerToCh() const { ... };
assuming you don't want anyone to modify the returned string from outside of the class.


Also, an assignment operator is usually declared as:
Code:
X & X::operator = (const X & other)
{
    // copy the contens from other

    return *this;
}
It will return itself, not a copy, so you can write like:
Code:
    (x = y) = z;

This applies for other operators, such as +, +=, etc.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.