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

Перегрузка операторов

22.05.2019, 11:46. Показов 1410. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет! Пытаюсь перегрузить оператор "+", в данном случае , по сути, реализовать конкатенацию строк. При компиляции выдает ошибку доступа для записи.

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
#include "pch.h"
#include <iostream>
#include <conio.h>
#include <string.h>
#include "cstring"
#include "MyString.h"
#include <iostream>
 
using namespace std;
 
MyString::MyString()
{
    s = new char[(ln = 0) + 1];
    s = '\0';
}
MyString::MyString(int n)
{
    s = new char[(ln = n) + 1];
    s = '\0';
}
MyString& MyString::operator +(MyString &str)
{
    MyString buffer(ln + str.ln + 1);
    int j = 0;
    for (int i = 0; i < ln; i++)
    {
        buffer.s[i] = s[i];
    }
    for (int i = ln + 1; i < ln + str.ln; i++)
    {
        buffer.s[i] = str.s[j];
        j++;
    }
 
    return buffer;
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.05.2019, 11:46
Ответы с готовыми решениями:

Что такое "перегрузка операторов"? Каковы принципы работы перегруженных операторов и назначение указателя this
Добрый день . Помогите понять принцип работы перегрузки операторов. объясните пожалуйста в зависимости от чего зависит агрумент при...

Перегрузка операторов
Я тут пока изучаю перегрузку, написал следующий код: class String{ private: size_t size_; char* data_; public: ...

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

17
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
22.05.2019, 12:01
Цитата Сообщение от Darcferus Посмотреть сообщение
MyString& MyString::operator +(MyString &str)
Убери ссылку у результата MyString MyString::operator +(MyString &str)
0
0 / 0 / 1
Регистрация: 01.11.2017
Сообщений: 36
22.05.2019, 12:09  [ТС]
Ошибка записи происходит в строке:

C++
1
buffer.s[i] = s[i];
Убирание ссылки не помогает.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
22.05.2019, 12:17
Цитата Сообщение от Darcferus Посмотреть сообщение
Убирание ссылки не помогает.
Позже поможет, это другая ошибка

Цитата Сообщение от Darcferus Посмотреть сообщение
Ошибка записи происходит в строке:
Покажи весь код, в частности как объявлен класс MyString

Добавлено через 4 минуты
Цитата Сообщение от Darcferus Посмотреть сообщение
s = '\0';
В конструкторах надо *s = '\0'

Добавлено через 39 секунд
Либо s[0] = '\0'
0
0 / 0 / 1
Регистрация: 01.11.2017
Сообщений: 36
22.05.2019, 12:19  [ТС]
MyString.h :
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
#pragma once
#include "pch.h"
#include <stdlib.h>
#include <iostream>
 
using namespace std;
 
class MyString
{
    char *s;
    int ln;
 
public:
    MyString();
    MyString(int);
    MyString(char*);
    MyString(const MyString &t);
    ~MyString();
    int Len();
    void assign(const MyString &t);
    void input();
    void output();
    void set(char st);
    char* output1() { return s; }
    int StrCmp(MyString s2);
 
    MyString& operator =(MyString &str);
    MyString& operator +(MyString &str);
    MyString& operator +=(MyString &str);
    bool operator ==(MyString &str);
    bool operator <=(MyString &str);
    bool operator >=(MyString &str);
    void operator <<(int n);
    void operator >>(int n);
 
};

MyString.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
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
#include "pch.h"
#include <iostream>
#include <conio.h>
#include <string.h>
#include "cstring"
#include "MyString.h"
#include <iostream>
 
using namespace std;
 
MyString::MyString()
{
    s = new char[(ln = 0) + 1];
    s = '\0';
}
MyString::MyString(int n)
{
    s = new char[(ln = n) + 1];
    s = '\0';
}
MyString::MyString(char *t)
{
    s = new char[(ln = strlen(t)) + 1];
    strcpy(s, t);
}
MyString::MyString(const MyString &t)
{
    s = new char[(ln = t.ln) + 1];
    strcpy(s, t.s);
}
MyString ::~MyString()
{
    delete[]s;
}
void MyString::assign(const MyString &t)
{
    if (&t == this)
        return;
    else
        s = new char[(ln = t.ln) + 1];
    strcpy(s, t.s);
}
void MyString::output()
{
    cout << s << endl;
}
void MyString::input()
{
    char buff[255];
    if (cin >> buff)
    {
        s = new char[(ln = strlen(buff)) + 1];
        strcpy(s, buff);
    }
    else return;
}
int MyString::Len()
{
    return ln;
}
int  MyString::StrCmp(MyString s2)
{
    return strcmp(s, s2.output1());
}
MyString& MyString::operator =(MyString &str)
{
    strcpy(s, str.s);
    return *this;
}
 
MyString& MyString::operator +(MyString &str)
{
    MyString buffer(ln + str.ln + 1);
    int j = 0;
    for (int i = 0; i < ln; i++)
    {
        buffer.s[i] = s[i];
    }
    for (int i = ln + 1; i < ln + str.ln; i++)
    {
        buffer.s[i] = str.s[j];
        j++;
    }
 
    return buffer;
}
 
bool MyString::operator ==(MyString &str)
{
    bool state = 0;
    if (ln == str.ln)
    {
        for (int i = 0; i < ln; i++)
        {
            if (s[i] == str.s[i])
            {
                state = 1;
                continue;
            }
            else {
                return 0;
            }
        }
    }
 
    return state;
}
 
bool MyString::operator <=(MyString &str)
{
    return (ln <= str.ln);
}
 
bool MyString::operator >=(MyString &str)
{
    return (ln >= str.ln);
}
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
22.05.2019, 12:20
Цитата Сообщение от Darcferus Посмотреть сообщение
MyString.h :
Выше написал, где ошибка
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Сообщение от Darcferus
s = '\0';
В конструкторах надо *s = '\0'
Добавлено через 39 секунд
Либо s[0] = '\0'
0
0 / 0 / 1
Регистрация: 01.11.2017
Сообщений: 36
22.05.2019, 12:31  [ТС]
Звездочки поставил. Убрал ссылки, но из-за этого перестал работать оператор "="(Visual Studio пишет "отсутствует оператор соответствующий этим операндам MyString = MyString"). Прога не компилируется.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
22.05.2019, 12:38
Цитата Сообщение от Darcferus Посмотреть сообщение
MyString& MyString::operator =(MyString &str)
Здесь нужно MyString& MyString::operator =(const MyString &str)

Добавлено через 53 секунды
То же самое для операторов + и +=

Добавлено через 19 секунд
И операторов сравнения

Добавлено через 40 секунд
Цитата Сообщение от Darcferus Посмотреть сообщение
int StrCmp(MyString s2);
int StrCmp(const MyString &s2);
0
0 / 0 / 1
Регистрация: 01.11.2017
Сообщений: 36
22.05.2019, 12:45  [ТС]
Понял. Вернул "&".
В общем теперь выходит ошибка "нарушение прав доступа при чтении по адресу 0xCCCCCCCC." у перегруженного оператора "=" в строке:
C++
1
strcpy(s, str.s);

Вот так кстати выглядит функция main:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
    setlocale(LC_ALL, "Russian");
    int max = 0, a = 0, n = 0, sw = -1, exit_key = 1;
    whRecord temp;
    MyString str1, str2, str3, str4;
    
    str1.input();
    str2.input();
    str3 = str1 + str2;
    str3.output();
        return 0;
}
А еще, в отладке, значение переменной buffer, после отработки обоих циклов выглядит вот так:
{s=0x0010d760 "123Н12ННээээЭЭЭЭ")aОЭ\x18" ln=7 }
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
22.05.2019, 12:56
Цитата Сообщение от Darcferus Посмотреть сообщение
В общем теперь выходит ошибка "нарушение прав доступа при чтении по адресу 0xCCCCCCCC." у перегруженного оператора "=" в строке:
Проверяй там длину строк, ты копируешь большую строку в маленкий буфер.
Вообще, там надо удалять старый буфер и выделыть новый соответствующего размера

Добавлено через 51 секунду
Цитата Сообщение от Darcferus Посмотреть сообщение
А еще, в отладке, значение переменной buffer, после отработки обоих циклов выглядит вот так:
{s=0x0010d760 "123Н12ННээээЭЭЭЭ")aОЭ\x18" ln=7 }
потому что ноль в концу не добавляешь
0
0 / 0 / 1
Регистрация: 01.11.2017
Сообщений: 36
22.05.2019, 13:35  [ТС]
Переделал вот так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
MyString& MyString::operator =(MyString &str)
{
    if (ln >= str.Len())
    {
        strcpy(s, str.s);
    }
    else {
        delete[]s;
        s = new char[(str.Len()) + 1];
        strcpy(s, str.s);
        s[ln] = '\0';
    }
    return *this;
}
Но str.Len() возвращает непонятно что (что то типа такого "-8927352735"). И я вот думаю, может при таком синтаксисе:
C++
1
str3 = str1 + str2;
нужно перегружать "=" с двумя параметрами? (MyString& MyString::operator =(MyString &str1, MyString &str2); )

Добавлено через 9 минут
Нет, 2 параметра не нужно по идее....
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
22.05.2019, 13:41
Цитата Сообщение от Darcferus Посмотреть сообщение
Но str.Len() возвращает непонятно что (что то типа такого "-8927352735").
Ты ln, которую там возвращаешь, где-нибудь присваиваешь?

Добавлено через 1 минуту
Цитата Сообщение от Darcferus Посмотреть сообщение
нужно перегружать "=" с двумя параметрами? (MyString& MyString::operator =(MyString &str1, MyString &str2); )
Нет не нужно.
А вот const добавить нужно - MyString& MyString::operator =(const MyString &str)
0
0 / 0 / 1
Регистрация: 01.11.2017
Сообщений: 36
22.05.2019, 13:43  [ТС]
Ну в теории, ln присваивается в конструкторе.

C++
1
2
3
4
5
MyString::MyString(int n)
{
    s = new char[(ln = n) + 1];
    *s = '\0';
}
Который, в данном случае вызывается при работе оператора "+" в строке:
C++
1
    MyString buffer(ln + str.ln + 1);
Когда я возвращаю buffer, ln этого буфера ведь тоже возвращается?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
22.05.2019, 13:49
Цитата Сообщение от Darcferus Посмотреть сообщение
s = new char[(str.Len()) + 1];
s = new char[(ln = str.Len()) + 1];

Добавлено через 43 секунды
Цитата Сообщение от Darcferus Посмотреть сообщение
Когда я возвращаю buffer, ln этого буфера ведь тоже возвращается?
Должна
0
0 / 0 / 1
Регистрация: 01.11.2017
Сообщений: 36
22.05.2019, 13:53  [ТС]
В отладке у str значение такое:

{s=0xcccccccc <Ошибка при чтении символов строки.> ln=-858993460 } ,

поэтому то и возвращается непонятно что. С str что-то не так.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
22.05.2019, 13:56
Лучший ответ Сообщение было отмечено Darcferus как решение

Решение

Цитата Сообщение от Darcferus Посмотреть сообщение
поэтому то и возвращается непонятно что. С str что-то не так.
Остальные строки нормальные?
Ссылку здесь точно убрал MyString& MyString::operator +(const MyString &str)?
1
0 / 0 / 1
Регистрация: 01.11.2017
Сообщений: 36
22.05.2019, 14:23  [ТС]
Ссылку убрал. Студия начала ругаться, пришлось убрать ссылку и у "=".
После этого студия ругается на str.Len(), "объект содержит квалификаторы типа, несовместимые с членом функцию "MyString::Len"

Добавлено через 5 минут
Сейчас все выглядит вот так:
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
#include "pch.h"
#include <iostream>
#include <conio.h>
#include <string.h>
#include "cstring"
#include "MyString.h"
#include <iostream>
 
using namespace std;
 
MyString::MyString()
{
    s = new char[(ln = 0) + 1];
    *s = '\0';
}
MyString::MyString(int n)
{
    s = new char[(ln = n) + 1];
    *s = '\0';
}
MyString::MyString(char *t)
{
    s = new char[(ln = strlen(t)) + 1];
    strcpy(s, t);
}
MyString::MyString(const MyString &t)
{
    s = new char[(ln = t.ln) + 1];
    strcpy(s, t.s);
}
MyString ::~MyString()
{
    delete[]s;
}
void MyString::assign(const MyString &t)
{
    if (&t == this)
        return;
    else
        s = new char[(ln = t.ln) + 1];
    strcpy(s, t.s);
}
void MyString::output()
{
    cout << s << endl;
}
void MyString::input()
{
    char buff[255];
    if (cin >> buff)
    {
        s = new char[(ln = strlen(buff)) + 1];
        strcpy(s, buff);
    }
    else return;
}
int MyString::Len()
{
    return ln;
}
int  MyString::StrCmp(MyString s2)
{
    return strcmp(s, s2.output1());
}
MyString MyString::operator =(const MyString &str)
{
    if (ln >= str.Len())
    {
        strcpy(s, str.s);
    }
    else {
        delete[]s;
        s = new char[(ln = str.Len()) + 1];
        strcpy(s, str.s);
        s[ln] = '\0';
    }
    return *this;
}
 
MyString MyString::operator +(const MyString &str)
{
    MyString buffer(ln + str.ln + 1);
    int j = 0;
    for (int i = 0; i < ln; i++)
    {
        buffer.s[i] = s[i];
    }
    for (int i = ln; i < ln + str.ln; i++)
    {
        buffer.s[i] = str.s[j];
        j++;
    }
 
    buffer.s[ln + str.ln] = '\0';
 
    return buffer;
}
 
bool MyString::operator ==(MyString &str)
{
    bool state = 0;
    if (ln == str.ln)
    {
        for (int i = 0; i < ln; i++)
        {
            if (s[i] == str.s[i])
            {
                state = 1;
                continue;
            }
            else {
                return 0;
            }
        }
    }
 
    return state;
}
 
bool MyString::operator <=(MyString &str)
{
    return (ln <= str.ln);
}
 
bool MyString::operator >=(MyString &str)
{
    return (ln >= str.ln);
}
Добавлено через 12 минут
Все заработало!!

Поменял просто str.Len() на str.ln

Спасибо большое за помощь
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
22.05.2019, 15:02
Цитата Сообщение от Darcferus Посмотреть сообщение
Студия начала ругаться, пришлось убрать ссылку и у "=".
Верни

Добавлено через 1 минуту
Цитата Сообщение от Darcferus Посмотреть сообщение
Поменял просто str.Len() на str.ln
Это ни на что не влияет

Добавлено через 3 минуты
Цитата Сообщение от Darcferus Посмотреть сообщение
После этого студия ругается на str.Len(), "объект содержит квалификаторы типа, несовместимые с членом функцию "MyString::Len"
Потому что ты вызывал его для константного объекта.
Сделай int Len() const;. Для операторов сравнения тоже. И для output().

Добавлено через 59 секунд
int StrCmp(MyString s2) const;

Добавлено через 29 секунд
MyString operator +(const MyString &str) const;

Добавлено через 44 секунды
В общем, все методы и операторы, которые не изменяют содержимое объекта должны быть объявлены как const
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.05.2019, 15:02
Помогаю со студенческими работами здесь

Перегрузка операторов
Доброго времени суток. на завтра надо сделать работу, а я не могу понять как использовать перегрузку операторов. помогите пожалуйста...

Перегрузка операторов
Здравствуйте уважаемые форумчане :) У меня имеется задание написать самодельный класс строки. Если с потоковым выводом я разобрался, то с...

Перегрузка операторов
Помогите проверить и сделать надо 1) Базовый класс Строка Описать базовый класс СТРОКА. Обязательные члены класса: * указатель...

Перегрузка операторов
Всем привет. Предположим, что нужно перегрузить оператор вывода &lt;&lt; для какого-то класса, определенного мной. Этот оператор должен выводить...

Перегрузка операторов
Исправьте ошибку, неуказанный тип возвращаемого значения, какая я то глупая ошибка, но я не могу понять На этой строке point1=point2+5;...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes. А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит токи на L и напряжения на C в установ. режимах до и. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru