C
We programmers should help each other.Let's start with the title. <cstring>#include <cstring>
Because you're using the functions declared in this heading.The length of the line is better defined as the type size_t instead int♪class String
{
char* s;
size_t length;
//...
Your designers are wrong to copy the lines. They don't copy the resulting zero symbol '\0'♪ For example,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];
}
Otherwise, it doesn't make sense why you're giving me the memory of the this->length+1 instead this->length♪
I don't know why you're using cycles to copy lines when you already use standard C functions from the heading. <cstring>It would be better to announce the designer as follows.String( const char *str = "" )
{
this->length = std::strlen( str );
this->s = new char[ this->length + 1 ];
std::strcpy( this->s, str );
}
The same point is true for the copy designer.The classification of the class cannot indicate the qualified name of the member functions of the class when they are declared. Although MS VC++ This allows, but this is his own expansion of a language that does not meet the standard.String& String::operator=(String& right);
^^^^^^^^
These announcementsString String::operator+(String right);
friend String& operator+=(String& left, const String& right);
better redesign as followsfriend String operator + ( const String &left, const String &right );
String & operator += ( const String &right );
Function show It's better to announce.std::ostream & String::show( std::ostream &os = std::cout ) const;
Reclassify the functions to reflect the above observations.For the copying operator of the attachment, it may be determined as follows: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;
}
Similarly, you need to identify the operator.String & operator += ( const String &right );
For exampleString & 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;
}
Function show simplystd::ostream & String::show( std::ostream &os ) const
{
return os << this->s;
}
As for your question.Почему у меня s3 всё равно при выводе пустая?
the operator.String& operator+=(String& left, const String& right)
{
return left+right;
}
doesn't change the left argument. Moreover, there is uncertainty as to how to return the reference to a temporary facility created by the expression left+right♪ EDIT: If the operator of the operator [] which I understand you must also determine, it is possible to place a symbol in the class object '\0', you should change the definitions of the copy designer copying the assignor, operator. operator +=and friendly functions operator +replacing standard C functions strXXX ♪ memXXX♪ The following is a demonstration programme which shows how this can be done in the example of some members of the class. Other members of the class will try to identify themselves.#include <iostream>
#include <cstring>
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;
}
The programme output will be as followsHello world!
Hello world! Glad to see you!