Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/21: Рейтинг темы: голосов - 21, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 01.10.2017
Сообщений: 3

Переопределение оператора [][]

01.10.2017, 10:27. Показов 4405. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет. Есть проблема с заданием из курса по С++:

В этой задаче вам требуется реализовать оператор [] для класса String. Оператор должен реализовывать нестандартное поведение: оператор нужно реализовать таким образом, чтобы для объекта str класса String можно было писать str[i][j] и это выражение возвращало подстроку начинающуюся в позиции i (считая с 0) и заканчивающуюся в позиции j (не включая).

Задание сделал, но оно не принимается на на сайте, пишет что течет память. Тестировал в VS при помощи CRT, все норм.

Перепробовал уже все варианты возврата SubString, первоначальный переопределения был такой, с отдельным деструктором для SubString:
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
const SubString& operator [](int a) const       // переопределиение для String
    {
        size_t newSize = size - a;
        char* tmp = new char[newSize+1];
        for (int i = a, j = 0; i < size; i++, j++)
        {
            tmp[j] = str[i];
        }
        tmp[newSize] = '\0';
        SubString subStr = new SubString(tmp, a);
        delete[] tmp;
        return *subStr;
    }
 
const String operator [](int a) const           // переопределиение для SubString
      {
           size_t newSize = a - first_index;
           char* tmp_str = new char[newSize + 1];
           for (int i = 0; i < newSize; i++)
            {
                tmp_str[i] = sub_str[i];
            }
            
               tmp_str[newSize] = '\0';
           String result(tmp_str);
           delete[] tmp_str;
           delete this;
        return result;
       }
VS не показало утечек. Потом почитал коменты, в одном из них куратор курса написал что нужно все делать без динамической памяти для String и SubString. Переделал, прогнал через проверку, все ок. На сайте тест сказал что утечка.
Прошу помочь разобраться, ниже привожу код без выделения динамической памяти для String и SubString:

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
struct String {
    String(const char *str = "")
    {
        size = stringLength(str);
        char* ss = new char[size + 1];
        copyString(ss, str);
        this->str = ss;
    }
    
    String(size_t n, char c)
    {
        size = n;
        char* tmp = new char[n + 1];
        fillStr(tmp, c);
        str = tmp;
    }
 
    ~String()
    {
        delete[] str;
        str = 0;
    }
 
    String(const String &other)
    {
        size = other.size;
        str = new char[size + 1];
        memcpy(this->str, other.str, size + 1);
    }
    
    String &operator=(const String &other)
    {
        if (this != &other)
        {
            delete[] str;
            size = strlen(other.str);
            this->str = new char[size + 1];
            memcpy(this->str, other.str, size + 1);
        }
        return *this;
    }
 
    struct SubString
    {
        SubString(const char *str = "", size_t first_index = 0)
        {
            size = stringLength(str);
            char* ss = new char[size + 1];
            copyString(ss, str);
            this->sub_str = ss;
            this->first_index = first_index;
        }
 
        const String operator [](int a) const                                          // переопределиение для SubString
        {
            size_t newSize = a - first_index;
            char* tmp_str = new char[newSize + 1];
            for (int i = 0; i < newSize; i++)
            {
                tmp_str[i] = sub_str[i];
            }
            tmp_str[newSize] = '\0';
            String result(tmp_str);
            delete[] tmp_str;
            delete[] sub_str;
            return result;
        }
        size_t first_index;
        size_t size;
        char* sub_str;
 
        int stringLength(const char* str)
        {
            int i = 0;
            while (str[i] != '\0')
            {
                i++;
            }
            return i;
        }
 
        void copyString(char* f, const char* str)
        {
            for (int i = 0; i <= (int)size; i++)
            {
                f[i] = str[i];
            }
        }
 
        void fillStr(char* str, char c)
        {
            for (size_t i = 0; i < size; i++)
            {
                str[i] = c;
            }
            str[size] = '\0';
        }
    };
 
    String(const SubString& ss)
    {
        copyString(this->str, ss.sub_str);
        this->size = ss.size;
    }
 
    const SubString operator [](int a) const                            // переопределиение для String
    {
        size_t newSize = size - a;
        char* tmp = new char[newSize+1];
        for (int i = a, j = 0; i < size; i++, j++)
        {
            tmp[j] = str[i];
        }
        tmp[newSize] = '\0';
        SubString subStr(tmp, a);
        delete[] tmp;
        return subStr;
    }
 
    void append(const String &other)
    {
        int newSize = size + other.size;
        char* res = new char[newSize + 1];
        for (int i = 0; i < (int)size; i++)
        {
            res[i] = str[i];
        }
        for (int old = size, ns = 0; old < newSize; old++, ns++)
        {
            res[old] = other.str[ns];
        }
        res[newSize] = '\0';
        size = newSize;
        delete[] str;
        str = res;
    }
    
    size_t size;
    char *str;
    
private:
    int stringLength(const char* str)
    {
        int i = 0;
        while (str[i] != '\0')
        {
            i++;
        }
        return i;
    }
 
    void copyString(char* f, const char* str)
    {
        for (int i = 0; i <= (int)size; i++)
        {
            f[i] = str[i];
        }
    }
 
    void fillStr(char* str, char c)
    {
        for (size_t i = 0; i < size; i++)
        {
            str[i] = c;
        }
        str[size] = '\0';
    }
};
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
01.10.2017, 10:27
Ответы с готовыми решениями:

Переопределение оператора
Переопределил оператор &quot;&quot;, как скрыть функцию &quot;operator&quot; так, чтобы она не была доступна при обращении вида object.methodName(); ? сам...

Переопределение оператора==
Создал функцию-операцию == для экземпляров класса, однако при выполнении данного кода Trigger.h #pragma once #include...

Переопределение оператора ==
Здравствуйте. Такая проблема: для поиска требуется сравнить два числа(в 1-ом случае инты, во 2-ом даблы). Для интов все отлично, а для...

5
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
01.10.2017, 12:29
Лучший ответ Сообщение было отмечено 1Juicer как решение

Решение

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
struct String {
    // ...
    // конструкторы и прочее
    //...
 
    struct SubStr;
    SubStr operator[](size_t i) const;
 
    size_t size;
    char *str;
};
 
struct String::SubStr
{
    SubStr(const String& s, size_t shft) : sub(s), shift(shft) {}
 
    String operator[](size_t i)
    {
        sub.str[i - shift] = 0;
        return String(sub.str);
    }
 
    String sub;
    size_t shift;
};
 
String::SubStr String::operator[](size_t i) const
{
    return String::SubStr(String(str + i), i);
}
1
0 / 0 / 0
Регистрация: 01.10.2017
Сообщений: 3
01.10.2017, 13:32  [ТС]
retmas, спасибо за ответ, очень элегантное и короткое решение. Однако ничего не понятно. На курсе еще не проходили ::, приблизительно понимаю что это оператор выбора пространства имен, но не более. Можно решить это более "деревянно", а желательно сказать где у меня ошибка? Понятно что там месиво, и реально так не кто не кодит, но я пока только учусь, и хотелось бы разобраться в основах.
0
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
01.10.2017, 14:09
куда уж деревяннее? в вашем коде же есть вложенная структура SubString. у меня то же, просто ее(SubStr) определение я вынес из определения структуры String. оттуда и непонятный вам ::
0
677 / 479 / 216
Регистрация: 06.09.2013
Сообщений: 1,312
01.10.2017, 15:24
1Juicer, скорее в качестве шутки, но может стоит подумать над этим:
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
#include <iostream>
 
class String {
    char * _data;
    size_t _size;
    size_t _offset;
public:
    String(char *src, size_t size, size_t offset = 0)
    : _data(src), _size(size), _offset(offset) {}
 
    String operator[](size_t i)
    { return  _offset ? String(_data, i - _offset, 0) : String(_data + i, _size - i, i);  }
 
    friend std::ostream & operator<<(std::ostream &os, const String &str);
};
 
std::ostream & operator<<(std::ostream &os, const String &str) {
    for(size_t i = 0; i < str._size; i++) std::cout << *(str._data + i);
    return os;
}
 
int main() {
    String str("12345678", 8);
    std::cout << str[2][6][2][4] << std::endl;
    return 0;
}
0
0 / 0 / 0
Регистрация: 01.10.2017
Сообщений: 3
01.10.2017, 22:09  [ТС]
retmas, Разобрался, спасибо, чуть переделал чтобы определение было в классе String.
Всем спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
01.10.2017, 22:09
Помогаю со студенческими работами здесь

Переопределение оператора
У меня есть класс вектора. Надо переопределить оператор умножения числа на вектор. class myvector { private: int x,y,z; public:...

Переопределение оператора ++
Необходимо переопределить оператор ++ в классе IteratorBase так, чтобы при этом вызывалась функция next(). template &lt;class T&gt;...

Переопределение оператора присваивания
Имеется такой простой класс: class TClass { private: float* A; int N; public: TClass(int _N) ...

Переопределение оператора == на объединения
В классе есть 3 линии: координаты 2 и 3 линий вводит пользователь.А координаты 1-ой (0;0)(суммам соответствующих координат конечных точек...

Переопределение оператора больше
Народ переопределял для сравнения знак больше но возникли траблы, выдается ошибочное значение, вот все исходники и скрины, не могу понять...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru