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

Реализовать оператор [] для класса String

15.10.2015, 13:54. Показов 19189. Ответов 10
Метки нет (Все метки)

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

Например:

C++
1
2
3
String const hello("hello");
String const hell = hello[0][4]; // теперь в hell хранится подстрока "hell"
String const ell  = hello[1][4]; // теперь в ell хранится подстрока "ell"
Обратите внимание, что i может равняться j, в этом случае результатом должна быть пустая строка. Гарантируется, что i никогда не будет больше j, и они не будут выходить за пределы длины строки.
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <cstddef> // size_t
 
struct String {
    String(const char *str = "");
    String(size_t n, char c);
    ~String();
 
    void append(const String &other);
 
    size_t size;
    char *str;
};
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
15.10.2015, 13:54
Ответы с готовыми решениями:

Реализовать оператор= для присваивания объекта класса-потомка объекту базового класса
Есть два класса A и B, причем класс B является потомком A. Как реализовать следующее: obj_A = obj_B и obj_B = obj_A? Добавлено через 9...

Реализовать оператор присваивания для класса куб
Дана длина ребра куба. Вычислить объем куба и площадь его боковой поверхности. Данные взять из контрольного примера. Контрольный пример:...

Реализовать метод append для класса String
Для работы со строками можно придумать множество полезных методов (подумайте, какие методы пригодились бы вам и чего вам не хватает для их...

10
 Аватар для ture
553 / 361 / 206
Регистрация: 27.11.2014
Сообщений: 1,049
15.10.2015, 14:00
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
#include <cstddef> // size_t
 
struct String {
    String(const char * str = "");
    String(size_t n, char c);
    ~String();
 
    void append(const String &other);
 
 void set_i(int i) const {
        this->i = i;
    }
 
    const String & operator[](int i) const {
        if(this->i < 0) {
            this->set_i(i);
            return *this;
        } else {
            char * str = new char[i - this->i + 1];
            for(int k = this->i, m = 0; k < i; ++k)
                str[m++] = this->str[k];
            str[i - this->i] = 0;
            this->set_i(-1);
            String * a=new String(str);
            delete [] str;
            return *a;
        }
        
    }   
    size_t size;
    char *str;
  private:
    mutable int i=-1;
};
0
0 / 0 / 0
Регистрация: 15.10.2015
Сообщений: 3
15.10.2015, 18:52
Однако Утечка памяти
Run time error:
terminate called after throwing an instance of 'std::logic_error'
what(): Memory leaks
0
 Аватар для ture
553 / 361 / 206
Регистрация: 27.11.2014
Сообщений: 1,049
16.10.2015, 09:40
arshor, не вижу пока где

Добавлено через 13 часов 3 минуты
Наверно, дипломы кончились на степике, и остальных велено завалить, ибо халявщики.
0
0 / 0 / 0
Регистрация: 21.05.2015
Сообщений: 7
17.10.2015, 13:44
очевидно, создается новый *a, но нигде не удаляется

C
1
String * a=new String(str);
0
 Аватар для ture
553 / 361 / 206
Регистрация: 27.11.2014
Сообщений: 1,049
17.10.2015, 21:46
a_swed, действительно. Как же я не догадался сразу...ммм? Как это исправить? Надо было только с одной стороны реализацию писать, значит не удалят сам блок тестирования.
0
0 / 0 / 0
Регистрация: 21.05.2015
Сообщений: 7
17.10.2015, 22:09
лично я не понял, о чем вы говорите в сообщении)
0
 Аватар для ture
553 / 361 / 206
Регистрация: 27.11.2014
Сообщений: 1,049
18.10.2015, 08:39
Это нормально. Задача обрисована примерно, никто объяснять детали не собирается, т. к. полагается догадаться самому. Программу трестирует сервис, ну наверно в нем и ошибка. Просто кому-то повезло, а кто-то не успел. Я могу предложить тем, кто не успел, замутить еще классик для хранения результата (там уже можно и деструктор реализовать), а "утечку" хранить в string, как член, т.е. ссылку выдавать как член данных другого класса. Да столько всего можно выдумать.... Главное утром начинать, когда голова свежая.
0
306 / 101 / 18
Регистрация: 04.07.2014
Сообщений: 571
18.10.2015, 17:05
Я бы предложил реализовать примерно вот так:
Кликните здесь для просмотра всего текста

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
namespace lab {
class String {
public:
    class PreparedString {
    public:
        void write(std::ostream& out) const;
        
        String operator[](unsigned int to) const;
        
        PreparedString(const String& source_in, unsigned int from_in);
        
    private:
        const String& source;
        unsigned int from;
    };
    
    void write(std::ostream& out) const;
    
    PreparedString operator[](unsigned int from) const;
    
    String(const char* c_str_in);
    
    ~String() throw();
    
private:
    char* c_str;
};
 
void String::PreparedString::write(std::ostream& out) const
{
    out << (this->source.c_str+this->from) << std::endl;
}
 
String String::PreparedString::operator[](unsigned int to) const
    {
        char *tmp_c_str = new char[to-from+1];
        for(char *at_src = source.c_str+from, *at_dst = tmp_c_str, *last = source.c_str+to; at_src != last; ++at_src, ++at_dst)
            *at_dst = *at_src;
        *(tmp_c_str+to-from) = '\0';
        String tmp_string(tmp_c_str);
        delete[] tmp_c_str;
        
        return tmp_string;
    }
    
String::PreparedString::PreparedString(const String& source_in, unsigned int from_in): source(source_in), from(from_in)
{
}
 
String::PreparedString String::operator[](unsigned int from) const
{
    return String::PreparedString(*this,from);
}
 
void String::write(std::ostream& out) const
{
    out << this->c_str << std::endl;
}
 
String::String(const char* c_str_in): c_str(0)
{
    c_str = new char[strlen(c_str_in)+1];
    strcpy(c_str,c_str_in);
}
 
String::~String() throw()
{
    delete[] c_str;
}
}///lab


Добавлено через 4 часа 50 минут
P.S. Ещё следует перегрузить конструктор копирования и оператор присваивания для lab::String.
Мой код относится только к архитектуре двойных скобок.
2
0 / 0 / 0
Регистрация: 08.10.2015
Сообщений: 3
21.10.2015, 15:57
mporro, спасибо Вам огромное!
Получилось реализовать следующим образом:
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
#include <cstddef> // size_t
#include <iostream>
 
struct String {
    String(const char *str = "");
    String(size_t n, char c);
    ~String();
 
    String(const String &other);
    String &operator=(const String &other);
 
    void append(const String &other);
    
    class PreparedString {
    public:
        void write(std::ostream& out) const;
        
        String operator[](unsigned int to) const;
        
        PreparedString(const String& source_in, unsigned int from_in);
        
    private:
        const String& source;
        unsigned int from;
    };
    
    void write(std::ostream& out) const;
    
    PreparedString operator[](unsigned int from) const;
    
    size_t size;
    char *str;
};
 
void String::PreparedString::write(std::ostream& out) const
{
    out << (this->source.str+this->from) << std::endl;
}
 
String String::PreparedString::operator[](unsigned int to) const
    {
        char *tmp_c_str = new char[to-from+1];
        for(char *at_src = source.str+from, *at_dst = tmp_c_str, *last = source.str+to; at_src != last; ++at_src, ++at_dst)
            *at_dst = *at_src;
        *(tmp_c_str+to-from) = '\0';
        String tmp_string(tmp_c_str);
        delete[] tmp_c_str;
        
        return tmp_string;
    }
    
String::PreparedString::PreparedString(const String& source_in, unsigned int from_in): source(source_in), from(from_in)
{
}
 
String::PreparedString String::operator[](unsigned int from) const
{
    return String::PreparedString(*this,from);
}
 
void String::write(std::ostream& out) const
{
    out << this->str << std::endl;
}
0
0 / 0 / 0
Регистрация: 22.10.2015
Сообщений: 1
22.10.2015, 15:53
Здравствуйте, пытаюсь решить ту же задачу через вложенные классы, однако не могу понять почему мой код не работает

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
#include <iostream>
#include <cstddef> // size_t
#include <cstring> // strlen, strcpy
using namespace std;
 
 
struct String {
    
    //Конструктор, принимающий на вход C-style строку
    String(const char *str = ""){
        int len = strlen(str);
        this->size=len;
        char* nstr = new char[len+1];
        strcpy(nstr,str);
        this->str = nstr;
    }
    
    //Заполняющий конструктор принимает число и символ, и создает строку 
    //с заданным количеством повторений переданного символа.
    String(size_t n, char c){
        
        this->size=n;
        char* nstr = new char[n+1];
            for(size_t i=0; i<n; i++){
            nstr[i]=c;
            }
        nstr[n+1]='\n';
        //strcpy(nstr,str);
        this->str = nstr;
    }
    
    //Конструктор копирования.
    String(const String &other)
        :size(other.size), str(new char[size+1])
        {
           for (size_t i=0; i<size; i++){ str[i]=other.str[i]; }
           str[size]='\0';
        }
 
    //деструктор
    ~String(){
        delete [] str; 
    }
        
    void swap(String &other){
        std::swap(size, other.size);
        std::swap(str, other.str);
    }
    
    //оператор присваивания
    String &operator=(String const &other){
        if(this != &other){
            String(other).swap(*this);
        }
        return *this;
    }
    
    /* доп структура */
    struct SubString{
        
        SubString(const char *str = "", size_t oldLen=0){
            int len = strlen(str);
            this->size=len;
            char* nstr = new char[len+1];
            strcpy(nstr,str);
            this->str = nstr;
            this->oldLen = oldLen;
        }
        
        ~SubString(){
            delete [] str; 
        }
        
        /* переопределение оператора [] для типа SubString */
        const String & operator[](unsigned index) const{
 
                char * nstr = new char[index];
                for (int i=0; i<index; i++){ 
                    nstr[i]=this->str[i]; 
                }
                nstr[index] = '\0';
                String strr(nstr);
                delete [] nstr;
                return strr;
                
        }
        
        size_t oldLen;
        size_t size;
        char *str;
    };
    
    /* переопределение оператора [] для типа String */
    const SubString & operator[](unsigned index) const{
        
            char * nstr = new char[size-index];
            for (int i=0; i<(size-index); i++){ 
                nstr[i]=this->str[i+index]; 
            }
            nstr[size-index] = '\0';
            SubString strr(nstr);
            delete [] nstr;
            return strr;
        
    }
       
    size_t size;
    char *str;
};
 
int main()
{
    String const strr("123456");
    cout<<strr[2].str<<"\n";            /* работает нормально */
    cout<<strr[0][2].str<<"\n";         /* не работает */
    
 
    int ext;
    std::cout<<"\n konec";
    std::cin>>ext;
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
22.10.2015, 15:53
Помогаю со студенческими работами здесь

Реализовать оператор умножения класса
Только начал работать с классами и мне не совсем понятно, как работать с операторами, вот что у меня получилось: class Matrix { ...

Для шаблонного класса перегрузить оператор присваивания, copy-конструктор, объекты cin и cout, оператор *
Помогите в следующем: Для класса шаблона следует перегрузить оператор присваивания, конструктор копирования, бинарный оператор суммы «*»,...

Реализовать аналог класса std::string с помощью vector
Помогите, пожалуйста, с кодом к заданию: Реализовать аналог класса std::string с помощью vector Заранее спасибо!

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

Реализовать оператор-функцию "-". String
Я новичок в программировании на С++, но базу знаю, на сколько можно знать новичку (строки я знаю хуже всего). Помогите с решением данной...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru