С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.94/18: Рейтинг темы: голосов - 18, средняя оценка - 4.94
2 / 2 / 0
Регистрация: 24.11.2016
Сообщений: 77
1

Ошибка после перегрузки оператора +

05.08.2017, 17:13. Показов 3279. Ответов 25
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте, решил для себя попробовать перегрузить оператор + в классе. Вроде все хорошо работает и результат
при складывании нескольких экземпляров класса выдает правильный результат, но вместе с результатом
появляется какая-то ошибка связанная, вроде, с памятью в куче. Вот моя программка:
Кликните здесь для просмотра всего текста
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
#include "stdafx.h"
#include <iostream>
 
using namespace std;
 
class String {
  
 private:
  char* str;
  int size;
 public:
 
     String(): size(0), str(0) {}
 
  String( const char* outStr ) { 
     if ( ! outStr ) {
            size = 0;
            delete [] str;
            str = 0; 
       }
     else {
        size = strlen(outStr);
        str = new char[size+1];
        strcpy( str, outStr );
     }
  }
 
  String( const String& rhs ) { 
        if ( ! rhs.size ) {
        size = 0;
            delete [] str; 
            str = 0;
    }
        else {
            size = rhs.size;
            str = new char[size];
            strcpy( str, rhs.str );
        }
  }
 
  ~String() { delete [] str; }
  
  String& operator=( const String& rhs ) {
           
           if ( ! rhs.size ) {
            size = 0;
            delete [] str; 
            str = 0;
           }
           else {
             size = rhs.size;
             str = new char[size+1];
             strcpy( str, rhs.str );
           }
 
          return *this;
    }
             
               
  String operator+( const String& rhs ) {
             String N3;
             N3.size = size + rhs.size;
             N3.str = new char[N3.size+1];
             strcpy( N3.str, str );
             strcat( N3.str, rhs.str );
             return N3;
}
         
 
  void ShowStr() { cout << str << endl; }
  void ShowSize() { cout << size << endl; }
 
};
 
int main()
{
    String N1("hello");
    String N2("World");
    String N3("Its Me");
    String N4 = N1 + N2 + N3;
    N4.ShowStr();
    N4.ShowSize();
    system("pause");
    return 0;
}


Ошибка в прикреплении. В чем я ошибся?
Миниатюры
Ошибка после перегрузки оператора +  
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.08.2017, 17:13
Ответы с готовыми решениями:

Ошибка перегрузки оператора
Здравствуйте уважаемые программисты, при созданиии проэкта возникает ошибка In function 'int...

Ошибка из книги оператора перегрузки
// Листинг 10.10. // Возвращение безымянного временного объекта #include &lt;string&gt; #include...

Ошибка при реализации перегрузки оператора <<
Добрый день. Прошу помощи. Имеется такой класc. class DList { ... public: ... void...

Ошибка в алгоритме перегрузки оператора присваивания
Добрый вечер. Пишу методы для класса по своему заданию. Столкнулся с проблемой перегрузки оператора...

25
Заблокирован
05.08.2017, 23:31 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от notAll Посмотреть сообщение
Это будет скорее всего обман пользователей так как у нас есть конструктор копий, который может кидать исключение. И обработать теперь этот ексепшин никто не сможет. Так что я бы так не писал.
noexcept обещает не генерировать исключений в теле функции. А конструкция аргументов происходит до вызова функции. Так что тут всё в порядке.
0
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
06.08.2017, 00:16 22
Тут дело не в noexcept, а в том что мы соврали пользователям, которые захотят написать безопасный код:
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
template <typename T>
void push_element_into_conteiner_impl(T&& t, std::true_type)
{
    // тут более еффективний код так как T обещает не кидать исключений
    // если надо сделать резайз контейнера, то все эллементы будут перемещены
 
    T some_temp_copy = t; // упс, ексепшын, а часть эллементов уже перемещена, что теперь делать?
    puts(__PRETTY_FUNCTION__);
}
 
template <typename T>
void push_element_into_conteiner_impl(T&& t, std::false_type)
{
    // тут менее эффективный код, так как наша функция должна иметь строгую гарантию безопасности
    // при ресайзе все эллементы сначала надо скопировать
    
    T some_temp_copy = t; // упс, ексепшын, но ничего страшного, - мы еще не затерли наши эллементы
    puts(__PRETTY_FUNCTION__);
}
 
template <typename T>
void push_element_into_conteiner(T&& t)
{
    push_element_into_conteiner_impl(std::forward<T>(t), typename std::is_nothrow_move_assignable<typename std::remove_reference<T>::type>::type());
}
 
int main()
{
    String s("Hello");
    push_element_into_conteiner(s);
}
0
Заблокирован
06.08.2017, 00:30 23
notAll, а при чём тут std::is_nothrow_move_assignable, если в функциях происходит не move, а copy и не assignment, а construction?
0
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
06.08.2017, 00:59 24
Цитата Сообщение от Tree depth Посмотреть сообщение
если в функциях происходит не move, а copy и не assignment, а construction
Не имеет значения; ну пускай будет присваивание. И перемещать пользователю возможно сразу и не надо:
C++
1
2
3
4
5
some_internal_conteiner[i] = t;
if (check_data(some_internal_conteiner[i]))
{
    data[last] = std::move(t);
}
0
Заблокирован
06.08.2017, 01:14 25
notAll, я не совсем понимаю, с чем ты хочешь поспорить.
Конструкция аргументов — это дело вызывающей стороны и noexcept у вызываемой функции никак не мешает ловить исключения, возникающие при конструкции аргументов.
Можно наконец самому проверить, что исключения в copy constructor-е при вызове оператора присваивания с noexcept прекрасно отлавливаются и не приводят к вызову std::terminate. Если лень проверять — можно погуглить https://stackoverflow.com/ques... swap-idiom

Добавлено через 10 минут
И ещё:
C++
1
2
3
4
// String& operator =(String rhs) noexcept
 
std::cout << std::is_nothrow_move_assignable<String>::value << '\n'; // true
std::cout << std::is_nothrow_copy_assignable<String>::value << '\n'; // false <-- !!!
Т.е. пользователя предупреждают, что если он будет использовать String& operator =(String rhs) noexcept как copy assignment оператор, то ему не гарантируется отсутствие исключений.

Так в чём же обман? Никакой разницы между String& operator =(String rhs) noexcept и версией с двумя операторами присваивания нет.
1
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
06.08.2017, 01:46 26
Да, так оно и есть, я был не прав.
1
06.08.2017, 01:46
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.08.2017, 01:46
Помогаю со студенческими работами здесь

Использование перегрузки оператора +
Есть у меня класс CPoint, с конструктором: CPoint::CPoint(float x, float y) { setX(x);...

Целесообразность перегрузки оператора
Изначально имелся такой вот метод (пусть будет методом класса &quot;A&quot;): //класс &quot;A&quot;, константная...

Friend-функции перегрузки оператора
Всем доброго времени суток =) У меня есть следующий код заголовочного файла: enum month {jan = 1,...

Вопрос по поводу перегрузки оператора +
Всем привет.Подскажите как можно перегрузить оператор + в моем классе? И что лучше вернуть из...


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

Или воспользуйтесь поиском по форуму:
26
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru