1 / 1 / 0
Регистрация: 11.12.2017
Сообщений: 44
1

Собственный класс String

20.12.2017, 12:57. Показов 1644. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Решила написать свой клас String. Но на в некоторых местах выдает ошибки. И мне кажеться что я все верно написала. Поэтому можете посмотеть и сказать как переделать и что не верно.
Код:
Header:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#pragma once
#include <iostream>
 
class String
{
public:
    String();
    String(const char& ch);
    String(const String& strOther);
    ~String();
 
    String& operator= (const String& str);
    String operator+ (const String& str) const;
    String operator+ (const char* ch) const;
    size_t GetSize();
    char& operator[] (size_t i);
 
    std::ostream& operator<< (std::ostream& os, const String& str);
 
private:
    size_t mLength;
    char* mChar;
};
CPP:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include "String.h"
 
String::String()
    : mLength(0)
    , mChar(nullptr)
{
}
 
String::String(const char& ch)
    : mLength(length(ch)) // тут кричит
    , mChar(new char[mLength + 1])
{
    for (int i = 0; i < mLength; ++i)
        mChar[i] = ch[i];   // тут кричит
}
 
String::String(const String& srtOther)
    : mLength(srtOther.mLength)
    , mChar(new char[mLength + 1])
{
    for (int i = 0; i < mLength; ++i)
        mChar[i] = srtOther.mLength[i];  // тут кричит
}
 
String::~String()
{
    delete[] mChar;
}
 
String& String::operator=(const String& str)
{
    if (this != &str)
    {
        mLength = str.mLength;
        delete[] mChar;
        mChar = new char[mLength];
        for (unsigned index = 0; index < mLength; ++index)
            mChar[index] = str.mChar[index];
    }
    return *this;
 
}
 
String String::operator+(const String& str) const  // не уверена в  правельно ли сделала  функцию
{
    char* temp = new char[mLength + str.mLength + 1];
    strcpy(temp, this->mChar);
    for (unsigned index = 0; index < mLength; ++index)
        temp[index] = mChar[index];
    for (unsigned index = 0; index < mLength; ++index)
        temp[index] = mChar[index] + str.mChar[index];
    String result(temp);
    delete[] temp;
    return result;
}
 
String String::operator+(const char* ch) const // не уверена в  правельно ли сделала  функцию
{
    size_t length = 0;
    if (mLength != 0)
        length = this->mLength + 2;
    else
        length = 2;
    char* temp = new char[length];
    if (mChar)
    {
        for (unsigned index = 0; index < mLength; ++index)
            temp[index] = mChar[index];
    }
    temp[length - 2] = ch;
    temp[length - 1] = '\0';
    String result(temp);
    delete[]temp;
    return result;
}
 
size_t String::GetSize()
{
    return mLength;
}
 
char& String::operator[](size_t i)
{
     return mChar[i];
}
 
std::ostream& String::operator<<(std::ostream& os, const String& str) // тут кричит
{
    for (int i = 0; i < str.size(); i++)
        os << str.mChar[i]; // тут кричит
    return os;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.12.2017, 12:57
Ответы с готовыми решениями:

Собственный класс String
Добрый день. Нужно реализовать класс String со следующими функциями: String(); String(const char...

Собственный класс итератора
Добрый день! Пишу сейчас одну библиотеку (не использующею STL и другие библиотеки) и для...

Собственный класс-итератор
Создаю класс-итератор для класса Студенты. Сам класс студенты: #ifndef STUDENTS_H #define...

STL и собственный класс
Подскажите, пожалуйста, как можно переопределить функцию STL для собственного класса. Например,...

20
2153 / 1663 / 701
Регистрация: 27.07.2012
Сообщений: 4,944
20.12.2017, 13:22 2
Ну а где ошибки-то?
0
1 / 1 / 0
Регистрация: 11.12.2017
Сообщений: 44
20.12.2017, 13:47  [ТС] 3
John Prick, я же оставила коменты где кричит.
Например:
C++
1
2
3
4
5
6
7
String::String(const char& ch)
    : mLength(length(ch)) // тут кричит
    , mChar(new char[mLength + 1])
{
    for (int i = 0; i < mLength; ++i)
        mChar[i] = ch[i];   // тут кричит
}

C++
1
2
3
4
5
6
7
8
9
10
11
String String::operator+(const String& str) const
{
    char* temp = new char[mLength + str.mLength + 1];
    for (unsigned index = 0; index < mLength; ++index)
        temp[index] = mChar[index];
    for (unsigned index = 0; index < mLength; ++index)
        temp[index] = mChar[index] + str.mChar[index];
    String result(temp); // тут кричит
    delete[] temp;
    return result;
}
и т.д
0
2153 / 1663 / 701
Регистрация: 27.07.2012
Сообщений: 4,944
20.12.2017, 13:57 4
Цитата Сообщение от olena_nov Посмотреть сообщение
String::String(const char& ch)
Это ссылка на 1 символ. Для строки надо const char* ch.
0
1 / 1 / 0
Регистрация: 11.12.2017
Сообщений: 44
20.12.2017, 14:52  [ТС] 5
John Prick, исправила
а тут что не правильно?
C++
1
2
3
4
5
6
7
String::String(const String& srtOther)
    : mLength(srtOther.mLength)
    , mChar(new char[mLength + 1])
{
    for (int i = 0; i < mLength; ++i)
        mChar[i] = srtOther.mLength[i];// ????
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
String String::operator+(const char* ch) const
{
    size_t length = 0;
    if (mLength != 0)
        length = this->mLength + 2;
    else
        length = 2;
    char* temp = new char[length];
    if (mChar)
    {
        for (unsigned index = 0; index < mLength; ++index)
            temp[index] = mChar[index];
    }
    temp[length - 2] = ch; // ???
    temp[length - 1] = '\0';
    String result(temp);
    delete[]temp;
    return result;
}
и тут
C++
1
2
3
4
5
6
std::ostream& String::operator<<(std::ostream& os, const String& str) // оно кричит на operator
{
    for (int i = 0; i < str.size(); i++) // тут на сайз
        os << str.mChar[i]; //  тут  на str.mChar[i]
    return os;
}
0
2153 / 1663 / 701
Регистрация: 27.07.2012
Сообщений: 4,944
20.12.2017, 15:08 6
Цитата Сообщение от olena_nov Посмотреть сообщение
mChar[i] = srtOther.mLength[i];
C++
1
mChar[i] = srtOther[i];
Цитата Сообщение от olena_nov Посмотреть сообщение
temp[length - 2] = ch; // ???
Тут не понимаю, что вы пытаетесь сделать.

Цитата Сообщение от olena_nov Посмотреть сообщение
std::ostream& String::operator<<(std::ostream& os, const String& str) // оно кричит на operator
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// .h
class String
{
    friend std::ostream operator<<(std::ostream &, const String&);
/*
    Всё то же самое, но убрать operator<<
    но добавить:
*/
    char operator[] const (size_t i);
};
 
//.cpp
char String::operator[] const (size_t i)
{
    return const_cast<String*>(this)->operator[](i);
}
 
std::ostream& operator<<(std::ostream& os, const String& str) // оно кричит на operator
{
    for (int i = 0; i < str.GetSize(); i++) // тут на сайз, потому что у вас нет size а есть GetSize
        os << str.mChar[i]; //  тут  на str.mChar[i] потому что нет константной версии operator[]
    return os;
}
0
1 / 1 / 0
Регистрация: 11.12.2017
Сообщений: 44
20.12.2017, 15:57  [ТС] 7
John Prick,
Severity Code Description Project File Line Suppression State
Error (active) no operator "[]" matches these operands String
0
2153 / 1663 / 701
Регистрация: 27.07.2012
Сообщений: 4,944
20.12.2017, 16:00 8
olena_nov, пардон, ошибся:
C++
1
2
3
4
5
6
char operator[] (size_t i) const;
 
char String::operator[](size_t i) const
{
    return const_cast<String*>(this)->operator[](i);
}
0
1 / 1 / 0
Регистрация: 11.12.2017
Сообщений: 44
21.12.2017, 12:05  [ТС] 9
C++
1
2
3
4
const char & String::operator[](size_t i) const
{
    return mChar[i];
}
Добавлено через 20 часов 0 минут
John Prick, а как реализовать оператор присвоения для чар?
C++
1
2
3
4
String& String::operator=(const char& other)
{
    //? ? ? ? ?
}
0
2153 / 1663 / 701
Регистрация: 27.07.2012
Сообщений: 4,944
21.12.2017, 12:11 10
Цитата Сообщение от olena_nov Посмотреть сообщение
а как реализовать оператор присвоения для чар?
А зачем он вообще? Что он должен делать?
0
1 / 1 / 0
Регистрация: 11.12.2017
Сообщений: 44
21.12.2017, 12:13  [ТС] 11
C++
1
2
String& operator= (const char& other);
    String& operator= (const char other);
Добавлено через 1 минуту
John Prick, хочу передавать char по значению
0
2153 / 1663 / 701
Регистрация: 27.07.2012
Сообщений: 4,944
21.12.2017, 12:15 12
olena_nov, так а что со строкой должно произойти при этом?
0
1 / 1 / 0
Регистрация: 11.12.2017
Сообщений: 44
21.12.2017, 12:26  [ТС] 13
я еще две функции написала:
C++
1
2
3
4
5
6
7
8
9
const char* String::GetBuffer() const
{
    return mString;
}
 
char* String::GetBuffer()
{
    return mString;
}
Добавлено через 32 секунды
John Prick, я хочу считывать не полностю рядок а кожное значения.
0
2153 / 1663 / 701
Регистрация: 27.07.2012
Сообщений: 4,944
21.12.2017, 12:31 14
Цитата Сообщение от olena_nov Посмотреть сообщение
я хочу считывать не полностю рядок а кожное значения.
Всё равно не понимаю. Если это функция для добавления символа в конец строки, то можно operator+= реализовать для символа. Но это не самая тривиальная задача, если делать по уму.
0
1 / 1 / 0
Регистрация: 11.12.2017
Сообщений: 44
21.12.2017, 13:32  [ТС] 15
John Prick, нет у меня есть функция operator+=
Я хочу еще написать два оператора присвоения
C++
1
2
String& operator= (const char& other);
    String& operator= (const char other);
у меня есть оператор
C++
1
String& operator= (const String& other);
а я хочу еще два таких написать только для чар

Добавлено через 40 минут
как то так:
но тут есть ошибки


C++
1
2
3
4
5
6
7
8
9
10
String & String::operator=(const char* other)
{
    delete[] mString;
    mSize = other.GetSize();
    mString = new char[mSize + 1];
    for (decltype(mSize) i = 0; i < mSize; ++i)
        mString[i] = other.GetBuffer;
    mString[mSize] = '\0';
    return *this;
}
0
2153 / 1663 / 701
Регистрация: 27.07.2012
Сообщений: 4,944
21.12.2017, 13:35 16
C++
1
2
3
4
5
6
7
8
9
10
String & String::operator=(const char* other)
{
    delete[] mString;
    mSize = strlen(other);
    mString = new char[mSize + 1];
    for (decltype(mSize) i = 0; i < mSize; ++i)
        mString[i] = other[i];
    mString[mSize] = '\0';
    return *this;
}
1
1 / 1 / 0
Регистрация: 11.12.2017
Сообщений: 44
21.12.2017, 13:53  [ТС] 17
John Prick, а тут как нужно?
C++
1
2
3
4
5
6
7
8
9
10
String & String::operator=(const char other)
{
    delete[] mString;
    mSize = other.GetSize();
    mString = new char[mSize + 1];
    for (decltype(mSize) i = 0; i < mSize; ++i)
        mString[i] = other.GetBuffer();
    mString[mSize] = '\0';
    return *this;
}
Добавлено через 2 минуты
C++
1
2
3
4
5
6
7
8
9
10
String & String::operator=(const char other)
{
    delete[] mString;
    mSize = std::strlen(&other);
    mString = new char[mSize + 1];
    for (decltype(mSize) i = 0; i < mSize; ++i)
        mString[i] = other[&i];
    mString[mSize] = '\0';
    return *this;
}
Добавлено через 17 секунд
но я думала через гетеры сделать
0
2761 / 1915 / 569
Регистрация: 05.06.2014
Сообщений: 5,571
21.12.2017, 13:57 18
Цитата Сообщение от olena_nov Посмотреть сообщение
John Prick, а тут как нужно?
C++
1
2
3
4
5
String & String::operator=(const char other)
{
    char str[]={other,0};
    return *this=str;
}
1
1 / 1 / 0
Регистрация: 11.12.2017
Сообщений: 44
21.12.2017, 14:32  [ТС] 19
Renji, не совсем поняла ваш код. Можете обяснить? Вы просто создали масив и записали туда озер?
а удалять не нужно
Код
delete[] mString;
?
0
15 / 16 / 6
Регистрация: 24.10.2017
Сообщений: 48
21.12.2017, 15:57 20
"и сказать как переделать"

примерно вот так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/* чтобы постоянно не выделять память при добавлении символов */
    const unsigned int StringWordSize = 16u;
 
    template<typename Type>
    class String{
 
    /* строка */
    Type * m_data;
 
    /* выделенная память */
    unsigned int m_allocated;
 
    /* размер строки */
    unsigned int m_size;
 
    /* выделение новой памяти */
    void reallocate( unsigned int new_allocated ){
 
        Type * new_data = new Type[ new_allocated ];
 
        if( m_data ){
            memcpy( new_data, m_data, m_allocated ); /* копирование старой строки в новую */
            delete []m_data;
        }else{
            memset( new_data, 0,  new_allocated );
        }
 
        m_data = new_data;
 
        m_allocated = new_allocated;
 
    }
 
    /* размер строки */
    unsigned int getlen( const Type* str ){
        unsigned int len = 0u;
        const Type * p = &str[ 0u ];
        while( *p++ ) len++;
        return len;
    }
 
    /* копирует src в dst */
    void copy( Type * dst, const Type* src ){
        while( *src ){
            *dst = *src;
            dst++;
            src++;
        }
    }
 
 
    public:
 
    String():
        m_size(0u),
        m_allocated(StringWordSize),
        m_data(nullptr)
    {
        reallocate( m_allocated );
    }
 
    String( const Type* str ):
        m_size(0u),
        m_allocated(StringWordSize),
        m_data(nullptr)
    {
        reallocate( m_allocated );
        assing( str );
    }
    
    String( const String& str ):
        m_size(0u),
        m_allocated(StringWordSize),
        m_data(nullptr)
    {
        reallocate( m_allocated );
        assing( str );
    }
    
    ~String(){
        if( m_data ){
            delete []m_data;
        }
    }
    
    /* присвоить */
    void assing( const Type * str ){
        /* типа очистили строку, просто поставили НОЛЬ вперёд */
        m_size = 0u;
        m_data[ m_size ] = 0x0;
 
        /* теперь можно добавить строку */
        append( str );
    }
 
    /* присвоить */
    void assing( const String& str ){
        /* типа очистили строку, просто поставили НОЛЬ вперёд */
        m_size = 0u;
        m_data[ m_size ] = 0x0;
 
        /* теперь можно добавить строку */
        append( str );
    }
 
    /* добавить в конец */
    void append( const Type * str ){
        u32 new_size = getlen( str ) + m_size;
 
        /* если размер больше выделенной памяти (учитывая НОЛЬ) */
        /* то выделяем ещё память + дополнительно StringWordSize*/
        if( (new_size + 1u) > m_allocated ){
            reallocate( (new_size + 1u) + StringWordSize );
        }
 
        copy( &m_data[m_size], str );
 
        m_size = new_size;
        m_data[ m_size ] = 0x0;
    }
 
    /* добавить в конец */
    void append( const String& str ){
        append( str.data() );
    }
 
    const Type * c_str( void ) const {
        return m_data;
    }
 
    const Type * data( void ) const {
        return m_data;
    }
 
    const unsigned int size( void ) const {
        return m_size;
    }
 
    String& operator=( const String& str ){
        assing( str );
        return *this;
    }
 
    String operator+( const Type* str ){
        String ret(*this);
        ret.append( str );
        return ret;
    }
 
    String operator+( const String& str ){
        return operator+(str.data());
    }
 
 
    const Type& operator[]( unsigned int i ) const {
        return m_data[ i ];
    }
 
    Type& operator[]( unsigned int i ){
        return m_data[ i ];
    }
 
    friend std::ostream& operator<<( std::ostream& os, const String& str );
 
    };
 
    std::ostream& operator<<( std::ostream& os, const String<char>& str ){
        os << str.data();
        return os;
    }
 
    using StringA = String<char>;
    using StringW = String<wchar_t>;
    using Stringu = String<char16_t>;
    using StringU = String<char32_t>;
так же можно сделать чтобы к char строке присоединить wchar и наоборот
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.12.2017, 15:57
Помогаю со студенческими работами здесь

Реализуйте собственный класс строки
Задание: Строка Реализуйте собственный класс строки для использования в языке C++. Класс...

Здравствуйте! Создал класс std::string. Не создается объкт типа string... Подскажите в чем причина?
#include &lt;stdlib.h&gt; #include &lt;iostream&gt; #include &lt;string.h&gt; //using namespace std; class...

Map и собственный класс: GCC ругается
Что я делаю не так? Мэйн: int main() { string s = &quot;abc&quot;; map&lt;string, ConfigSection&gt;...

Вывод двумерного массива используя собственный класс
Доброго времени суток! дайте совет что не так сделал. нужно вывести двумерный массив с помощью...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru