Консультация № 30707
03.12.2005, 15:30
0.00 руб.
0 5 3
Вопрос такой. Есть задание на лабу: написать класс mystring, перегрузить там операторы и т.д.
В приложении - код класса.
Вопрос такой. Как корректно, чтобы не придрались вернуть из класса объект?
И вообще, к чему можно придраться в этом классе? Ну, точнее не придраться, а что можно сделать лучше?

Приложение:
#include <string.h>class string{public: string(const char *);//constructor int GetLen() const;//length of string string Left(int);//returns n chars from left string Right(int);//returns n chars from right string Mid(int, int);//returns n chars from m position int Find(char) const;//returns index of target character void Print() const;//prtints string to stdout char* Value();//returns string void operator =(const char*);//reloading = operator, assign string operator +(const char*);//contatenate & return void operator +=(const char*);//concatenate char operator [](int);//return specified char int operator ==(const char*);//compare string and char* int operator ==(const string);//compare strings int operator !=(const char*);//compare string and char* int operator !=(const string);//compare stringsprivate: char data[255];//data int length;//length of the string};string::string(const char newdata[255])//constructor{ strcpy(this->data, newdata);//copy data this->length = strlen(this->data);//caluclate length}int string::GetLen() const//returns length{ return this->length;}string string::Left(int num)//getting n chars from the left{ //if number of symbols is more than length of string, we return all sting string str = this->data; if (num >= this->length) return *this; char result[255]; for (int i = 0; i < num; i++) { result[i] = this->data[i]; } result[i] = 0;//and terminate string str = result; return str;}string string::Right(int num)//gettin n chars from the end{ //if number of symbols is more than length of string, we return all sting if (num >= this->length) return *this; char result[255]; num = this->length - num;//calcualting start index //copying all symbols for (int i = num, j = 0; i < this->length; i++, j++) { result[j] = this->data[i]; } result[j] = 0;// and terminate string string str(result); return result;}string string::Mid(int start, int length)// getting n chars from the m position{ string str(""); if (start+1 > this->length) return str;//if start char is greater than string length char result[255]; //calculating last index int last = (start + length + 1 > this->length ? this->length : start + length); //copying string to result var for (int i = start, j = 0; i < last; i++, j++) { result[j] = this->data[i]; } result[j] = 0;//terminate str with null char str = result; return str;}int string::Find(char symbol) const//function serches for character and returns its index//or -1 if it was not found{ for (int i = 0; i < this->length; i++) { if (symbol == this->data[i]) return i; } return -1;}char * string::Value()//returns value{ return this->data;}void string::Print()const//prints to stdout{ printf("%s", this->data);}void string::operator =(const char * newdata)//assigns new data, similar to constructor{ strcpy(string::data, newdata); string::length = strlen(string::data);}string string::operator +(const char * newdata)//adds data to the current string and returns concatenated variant. //source string is not changed{ char result[255]; strcpy(result, this->Value()); string str(strcat(result, newdata)); return str;}void string::operator +=(const char * newdata)//adds data to current string{ strcat(this->data, newdata); this->length = strlen(this->data);}int string::operator ==(const char * cmpdata)//compares char* data with a standart function,{ return !strcmp(string::data, cmpdata);}int string::operator ==(string cmpdata)//compares string data with a standart function,{ return !strcmp(this->data, cmpdata.Value());}int string::operator !=(const char * cmpdata)//compares char* data with a standart function{ return strcmp(string::data, cmpdata);}int string::operator !=(string cmpdata)//compares string data with a standart function,{ return strcmp(this->data, cmpdata.Value());}char string::operator [](int index)//returns character by index{ if (index >= this->length) { return 0; } return this->data[index];}

Обсуждение

Неизвестный
03.12.2005, 16:13
общий
это ответ
Здравствуйте, Константин!
Логично возвращать ссылку на char в operator[], чтобы можно было писать string s; ... s[3] = ‘A‘;
Print лучше делать не на экран, а в поток.
Я бы добавил отладочные функции, например Dump и IsValid
Еще можно работать через аллокатор, если класс насчитан на динамическую работу. К тому же, в данном виде этот класс работает только с однобайтовыми символами, а было бы неплохо работать через шаблон с любыми char_traits
Неизвестный
03.12.2005, 16:56
общий
А как возвращать ссылку на char? Что имеетсяв виду?И все же меня интересует корректное возврещение объекта в методах Left, Right, Mid, операции +
Неизвестный
03.12.2005, 16:59
общий
это ответ
Здравствуйте, Константин!
1. добавить пустой конструктор или привести первый к значению по-умолчанию
string(const char * str = NULL);
2. переменную char data[255]; заменить на char * data и создавать ее динамически, в контрукторе принимать буфер как (const char * newdata), а не как (const char newdata [255]). Нельзя так ограничивать класс.
3. добавить виртуальный деструктор, соотв. в нем чиститься
virtual ~string ();
4. добавить Find (char *) - т.е. поиск не только символа, но и строки
5. функции типа GetLen сделать inline
6. из функции Value возвращать константную строку, или перегрузить ее двумя спосбобами
7. ИМХО, слишком много ненужных this
8. Print дейстивтельно смотриться слишком узкоспециализированно
9. в функциях сравнения посоветовал бы возвращать то, что возвращает strcmp, все таки люди привыкли что 0 означает равенство, или хорошо закоментировать эту фугкцию, если делаешь наоборот
10. Сделать класс одинаково работающим как с АНСИ, так и с ЮНИКОД - строками.
пс
сам код и алгоритмы не смотрел, нету времени, звини
Неизвестный
03.12.2005, 23:21
общий
это ответ
Здравствуйте, Константин!
А зачем тебе лучше, класс явно не для практического использования из-за малой длины строки, чтобы корректно вернуть объект нужно его корректно конструировать, чего в твоем случае не наблюдается. Тебе надо создать конструктор копий (пишу как будто он inline, т.е. в объявлении) и оператор присваивания.
string(const string& src )
{
strcpy(this->data, newdata);
length=strlen(this->data);
}
string& operator =(const string& src)
{
strcpy(this->data, newdata);
length=strlen(this->data);
return *this;
}
________________________________________________
возможно будет работать и без этого если добавить оператор
operator const char*() const
{
return data;
}
тогда будет корректно работать конструктор и оператор присваивания из char*
_____________________________________________________________
по коду:
1.
string::string(const char newdata[255])//constructor
надо заменить на
string::string(const char* newdata)
иначе при вызове придется постоянно использовать приведение
2.
this->data // зачем везде использовать this, у тебя почти нигде нет неоднозначности, по моему это просто захламляет код
3. Вообще код очень сырой и весьма далек от оптимального, например
for (int i = num, j = 0; i < this->length; i++, j++)
{
result[j] = this->data[i];
}
можно заменить одним оператором memcpy
4. В функции
string string::Right(int num)//gettin n chars from the end
ты пытаешься вернуть не то что надо
5. Зачем нужна функция Print, или эта строка предназначена только для DOS или консоли?
6. Во операторах +,+= отсутствует проверка на размер
______________________________________________________
Вообще написать толковую и удобную строку достаточно объемная работа, я этим занимался но понял, что совершенство недостижимо. В текущем состоянии в ней около 120 функций и 100 кб исходник, и много нереализованных усовершенствований. Если она тебе нужна для зачета, то доведи до ума то что уже есть, если для работы то попробуй использовать ее в 5-6 программах и сам поймешь чего в ней не хватает. Как минимум динамического выделения буфера. В качестве базы посмотри на реализацию CString в MFC, там есть чему поучиться.
Неизвестный
05.12.2005, 09:29
общий
string(const string& src ) { strcpy(this->data, newdata); length=strlen(this->data); }а где в параметрах newdata???и какой объект я по ссылке получаю?Блин, не могу в это въехать... Может есть что-то про возврат объектов почитать?
Форма ответа