// Реализовать класс String для работы со строками. Перегрузить операторы = + += - > < [] (подстрока) ++ --
#pragma once
#include
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");
}
Ответ
Мы, начинающие программисты, должны помогать друг другу.:)
Начнем с того, что вам следует включить заголовок
#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
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!
Комментариев нет:
Отправить комментарий