For training, I’m trying to write a class like std::string.
I have read that the method at(int) returns the reference to a character and throws an exception in the case the index is wrong (too long, or negative).
The operator[] instead doesn’t throw any exception.
But since it returns a reference, if the index is too long, what does it return?
This is the class I have:
class string
{
public:
static const unsigned int length_max=100;
string(const char* field=NULL)
{
if(field!=NULL)
{
const unsigned int length=strlen(field);
this->field=new char[length+1];
this->length=length;
for(unsigned int i=0;i<=length;i++)
this->field[i]=field[i];
}
else
{
this->field=NULL;
length=0;
}
}
string& operator=(const char* field)
{
const unsigned int length=strlen(field);
if(this->field!=NULL)
delete this->field;
this->field=new char[length];
this->length=length;
for(unsigned int i=0;i<length;i++)
this->field[i]=field[i];
return *this;
}
string& operator= (const string& str)
{
*this=str.field;
return *this;
}
operator char* ()
{
return field;
}
friend std::ostream& operator<< (std::ostream& out, string& str);
friend std::istream& operator>> (std::istream& in, string& str);
private:
char* field;
unsigned int length;
};
std::ostream& operator<<(std::ostream& out, string& str)
{
out << str.field;
return out;
}
std::istream& operator>> (std::istream& in, string& str)
{
char temp[string::length_max];
in >> temp;
str=temp;
return in;
}
I want to make the operator[], I also could make it throw an exception, but the problem is that I don’t know what shall it return in the case the index is too long.
For example the operator[] overloading is this:
char& operator[] (int i)
{
try
{
if(i<0 || i>=length)
throw indexException();
return field[i];
}
catch(indexException& e)
{
std::cerr << e.what() << std::endl;
}
}
This is the exception:
class indexException:std::exception
{
public:
virtual const char* what()
{
return "Index is either too long, or negative";
}
};
It has to return a char reference and not only a char because I want to make it assignable, so for example if I have a string str I could say str[5]=’c’.
I also want to handle the exception, and not to quit the program with exit().
So if there is an exception it doesn’t return any value, the string could also be empty.
What should I return? I would make it similar to std::string but I haven’t understood very well how the one of std::string is implemented.
There’s not much point to throwing an exception if you’re going to catch it in the same block. Just have your
ifstatement control things if you wish to return something rather than throwing the error outside of your function.The standard string class doesn’t do any checking whatsoever on its index so that there’s no added overhead. If an index is out of bounds you get undefined behavior, because you’re using an out of bounds index on the internal buffer.
You can choose whatever you want to return for out of bounds indexes. Zero would be a good choice as this would indicate the end of a C-style string.