#cpp #строки #классы #перегрузка_операторов #конструктор
// Реализовать класс String для работы со строками. Перегрузить операторы = + += - > < [] (подстрока) ++ -- #pragma once #includeusing namespace std; class String { char* s; int length; public: String(const char* str="") { this->length = strlen(str); this->s = new char[this->length+1]; for (int i = 0; i < length; i++) this->s[i] = str[i]; } String(const String& s1) { this->length = s1.length; this->s = new char[this->length]; for (int i = 0; i < this->length; i++) this->s[i] = s1.s[i]; } ~String() { delete[] s; } String& String::operator=(String& right); String String::operator+(String right); //String& String::operator+=(const String& right); friend String& operator+=(String& left, const String& right); void String::show(); }; А это цпп файл: #include "String.h" void String::show() { for (int i = 0; i < this->length; i++) cout << this->s[i]; } String& String::operator=(String& right) { delete[] this->s; this->length = right.length; this->s = new char[this->length]; for (int i = 0; i < this->length; i++) this->s[i] = right.s[i]; return *this; } String String::operator+(String right) { String new_string; new_string.length = this->length + right.length; new_string.s =new char[this->length + right.length+1]; for (int i = 0; i < this->length; i++) new_string.s[i] = this->s[i]; for (int i = 0; i < right.length; i++) new_string.s[this->length + i] = right.s[i]; return new_string; } String& operator+=(String& left, const String& right) { return left+right; } Почему у меня s3 всё равно при выводе пустая? Помогите начинающему! #include "String.h" void main() { String s2("Hello"); String s3; s3 += s2; s3.show(); system("pause"); }
Ответы
Ответ 1
Мы, начинающие программисты, должны помогать друг другу.:) Начнем с того, что вам следует включить заголовок#include так как вы используете функции, объявленные в этом заголовке. Длину строки лучше определять, как имеющую тип size_t вместо int. class String { char* s; size_t length; //... Ваши конструкторы неверно копируют строки. Они не копируют в результирующую строку завершающий символ нуля '\0'. Например, String(const char* str="") { this->length = strlen(str); this->s = new char[this->length+1]; for (int i = 0; i < length; i++) // символ нуля не входи в диапазон `[0, length)` this->s[i] = str[i]; } Иначе непонятно, зачем вы выделяете память длиною this->length+1 вместо this->length. Непонятно, зачем вы вообще используете циклы для копирования строк, когда вы уже используете стандартные C функции из заголовка Лучше было бы объявить конструктор следующим образом String( const char *str = "" ) { this->length = std::strlen( str ); this->s = new char[ this->length + 1 ]; std::strcpy( this->s, str ); } То же самое замечание справедливо и для конструктора копирования. В определении класса нельзя указывать квалифицированное имя функций-членов класса при их объявлении. Хотя MS VC++ это допускает, но это является его собственным расширением языка, которое не соответствует стандарту. String& String::operator=(String& right); ^^^^^^^^ Эти объявления String String::operator+(String right); friend String& operator+=(String& left, const String& right); лучше переопределить следующим образом friend String operator + ( const String &left, const String &right ); String & operator += ( const String &right ); Функцию show лучше объявить как std::ostream & String::show( std::ostream &os = std::cout ) const; Переопределите соответствующие функции с учетом выше приведенных замечаний. Что касается копирующего оператора присваивания, то он может быть определен следующим образом String & String::operator =( const String &right ) { if ( this != &right ) { size_t n = std::strlen( right.s ); char tmp = new char[ n + 1 ]; std::strcpy( tmp, right.s ); delete [] this->s; this->s = tmp; this->length = n; } return *this; } Аналогичным образом вам нужно определить оператор String & operator += ( const String &right ); Например String & String::operator +=( const String &right ) { size_t n = this->length + std::strlen( right.s ); char tmp = new char[ n + 1 ]; std::strcpy( tmp, this->s ); std::strcat( tmp, right.s ); delete [] this->s; this->s = tmp; this->length = n; return *this; } Функция show определяется просто std::ostream & String::show( std::ostream &os ) const { return os << this->s; } Что касается вашего вопроса Почему у меня s3 всё равно при выводе пустая? то этот оператор String& operator+=(String& left, const String& right) { return left+right; } не изменяет левый аргумент. И более того имеет неопределенное поведение, так как возвращает ссылку на временный объект, создаваемый выражением left+right. EDIT: Если оператор operator [], который, как я понимаю, вы также должны определить, позволяет вставлять в объект класса символ '\0', то вам следует изменить определения конструктора копирования, копирующего опреатора присваивания, оператора operator +=, и дружественной функции operator +, заменив стандартные C функции strXXX на memXXX. Ниже приведена демонстрационная программа, которая показывает, как это можно сделать на примере некоторых членов класса. Другие члены класса постарайтесь определить сами. #include #include class String { private: char *s; size_t length; public: String( const char *str = "" ) { this->length = std::strlen( str ); this->s = new char[ this->length + 1 ]; std::strcpy( this->s, str ); } String( const String &src ) { this->length = src.length; this->s = new char[ this->length + 1 ]; std::memcpy( this->s, src.s, this->length + 1 ); } String & operator =( const String &src ) { if ( this !=+ &src ) { char *tmp = new char[ src.length + 1 ]; std::memcpy( tmp, src.s, src.length + 1 ); delete [] this->s; this->s = tmp; this->length = src.length; } return *this; } String & operator +=( const String &src ) { size_t n = this->length + src.length; char *tmp = new char[ n + 1 ]; std::memcpy( tmp, this->s, this->length ); std::memcpy( tmp + this->length, src.s, src.length + 1 ); delete [] this->s; this->s = tmp; this->length = n; return *this; } ~String() { delete [] this->s; } std::ostream & show( std::ostream &os = std::cout ) { return os << this->s; } }; int main() { String s1( "Hello world!" ); String s2; s2 = s1; s2.show() << std::endl; s2 += " Glad to see you!"; s2.show() << std::endl; return 0; } Вывод программы будет следующим Hello world! Hello world! Glad to see you!
Комментариев нет:
Отправить комментарий