Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 5.00/8: Рейтинг темы: голосов - 8, средняя оценка - 5.00
15 / 15 / 4
Регистрация: 11.11.2014
Сообщений: 122

Приведение типов в классе

26.05.2015, 22:44. Показов 2107. Ответов 35
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день всем, кто увлекается.

Столкнулся с такой проблемой. Есть класс String (костыль собственного производства). Хочу перегрузить операцию сложения с прототипом:

C++ (Qt)
1
friend String operator+(const String &, const String &)
Вот кусок кода:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
String::String(const char * s)
{
    len = strlen(s);
    str = new char[len+1];
    strcpy(str,s);
    num_strings++;
}
 
String::String()
{
    len = 0;
    str = new char[1];
    str[0] = '\0';
    num_strings++;:
}
 
String operator+(const String & st1, const String & st2) 
{   
    return String(std::strcat(st1.str, st2.str));
}
Хочу с таким определением сделать сложение:
C++ (Qt)
1
2
3
String a("Vasya");
String b;
b = "Katya " + a;
Сейчас программа вылетает с руганью на памяти. Можно ли грамотно перегрузить операцию сложения, чтобы она умела работать с таким определением. Как вариант написать явное приведение из char в структуру класса (пока ни одной мысли на эту тему). Или придётся перегружать операцию сложения в остальных двух случаях, когда одна из переменных const char *?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
26.05.2015, 22:44
Ответы с готовыми решениями:

Приведение типов
Привет всем! Компилятор выдает варнинг если сравниваются signed и unsigned значения.Допустим, код пересмотреть нельзя и изменить типы...

Приведение типов
Есть ли какая-нибудь разница в следующих выражениях: float a = 123.4f и float a = (float)123.4

приведение типов
Объясните, пожалуйста, почему возникает такая ошибка: error C2666: 'operator *' : 4 overloads have similar conversions ? Из-за того,...

35
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
28.05.2015, 00:06
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от castaway Посмотреть сообщение
Я говорю о правильном подходе, а не о через-жопном.
Лично мне не понятны твои претензии к коду Perfilov. По-моему вполне достойный подход к решению проблемы.
Ну или в реализации стандартной библиотеки, по-твоему, подход через-жопный?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  // operator+
  /**
   *  @brief  Concatenate two strings.
   *  @param __lhs  First string.
   *  @param __rhs  Last string.
   *  @return  New string with value of @a __lhs followed by @a __rhs.
   */
  template<typename _CharT, typename _Traits, typename _Alloc>
    basic_string<_CharT, _Traits, _Alloc>
    operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
          const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    {
      basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
      __str.append(__rhs);
      return __str;
    }
Если ты серьезно так считаешь, то предлагаю это обосновать.
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
28.05.2015, 00:12
DrOffset, мм.. а где связь о том что я говорил с тем что ты предоставил?
Под "через-жопным" я подразумевал обязательный неконстантный lhs.
0
 Аватар для Nosey
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
28.05.2015, 00:12
Цитата Сообщение от Perfilov Посмотреть сообщение
сигнатуры не совпадают специально. иначе к константному аргументу lhs нельзя будет применить неконстантный operator +=
Только зачем превращать оператор + в +=?
Это не просто сокращение строк, это чёрная магия которую надо бояться.(я про "//ну или:" вариант)

Не по теме:

castaway, Что-то нынче не в настроении :)

0
28.05.2015, 00:14

Не по теме:

Не по теме:

Цитата Сообщение от Nosey Посмотреть сообщение
castaway, Что-то нынче не в настроении:)

Всё норм:)

0
265 / 165 / 56
Регистрация: 25.02.2015
Сообщений: 435
28.05.2015, 00:18
я вот пока сочинял тут уже понаписали. тем не менее:

а мне все больше становится понятно, что я тебя лично чем-то задел. чем - хз.
я привел два примера. первый почти по всем канонам, второй - альтернатива для любителей писать хитрый код ради экономии пары строк кода.

примеры были приведены по запросу типа, покажи на сколько это просто.
примеры приведены, они простые. несовпадение сигнатур могло быть и опечаткой, однако простота реализации
была бы понятна даже новичку. тебе понадобилось зачем-то докопаться до этого и даже после пояснений что к чему - ты продолжаешь. Что значит допустим тебе нужны? ну нужны, не используй второй вариант. В случае наследников можем получить срезку объекта, которая все испортит. Хотя выглядит надуманно. Есть еще варианты? Если есть - опять же не используй.

По поводу авторитетов: Страуструп в своей книге приводит примеры именно такой реализации. Недостаточно авторитетно? Ну извини, добавить тут больше нечего.
0
 Аватар для Nosey
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
28.05.2015, 00:24
Цитата Сообщение от DrOffset Посмотреть сообщение
Ну или в реализации стандартной библиотеки
Чёрт, там же реалокация будет бонусная Мой мир перевернулся, а я так верил в стл
0
265 / 165 / 56
Регистрация: 25.02.2015
Сообщений: 435
28.05.2015, 00:26
до кучи еще раз процитирую сам себя:
Про эффективность речи пока не было. Если вдруг зайдет, то и тот и другой оператор наверно
лучше будет делать через какие-нибудь общие спец методы или функции.
и смотрим на код от DrOffset: append - тот самый спец метод. наверняка operator += тоже его юзает
или что-то подобное. лень смотреть в исходники
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
28.05.2015, 00:38
Цитата Сообщение от Nosey Посмотреть сообщение
Чёрт, там же реалокация будет бонусная
Необязательно. Память выделяется с запасом (вспомним про capacity). Если вторая строка не очень длинная, то она вполне влезет в этот запас. Ну а с очень длинными строками у нас проблемы уже другого рода. В любом случае, ждать от generic средства идеальной работы на всем возможном варианте входных данных - очень наивно

Добавлено через 8 минут
Nosey, В добавок к этому, реализацию можно улучшить, например, встречается и такой вариант (это из студии 2013):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
template<class _Elem,
    class _Traits,
    class _Alloc> inline
    basic_string<_Elem, _Traits, _Alloc> operator+(
        const basic_string<_Elem, _Traits, _Alloc>& _Left,
        const basic_string<_Elem, _Traits, _Alloc>& _Right)
    {   // return string + string
    basic_string<_Elem, _Traits, _Alloc> _Ans;
    _Ans.reserve(_Left.size() + _Right.size());
    _Ans += _Left;
    _Ans += _Right;
    return (_Ans);
    }
Хотя изначальный принцип в целом сохранен.
0
 Аватар для Nosey
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
28.05.2015, 00:40
Цитата Сообщение от DrOffset Посмотреть сообщение
Необязательно. Память выделяется с запасом (вспомним про capacity). Если вторая строка не очень длинная, то она вполне влезет в этот запас. Ну а с очень длинными строками у нас проблемы уже другого рода. В любом случае, ждать от generic средства идеальной работы на всем возможном варианте входных данных - очень наивно
Это да, ну и сейчас проверил, в gcc коэффициент костантный и равен 2 у строк. -> таки миссы на примерно равных строках будут нередкими. Уж можно было в + сложить предварительно размеры, это не такой редкий оператор, обидно мальца

Добавлено через 1 минуту
Вот второй вариант - это отлично, и ведь не сложно. Эх, ГыЦыЦы
0
 Аватар для Nosey
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
28.05.2015, 01:00
Цитата Сообщение от castaway Посмотреть сообщение
В его реализации первый операнд - временная переменная
Perfilov, Сорри, я не доглядел, подумал что там ссылка чёрная магия превращается в серенькую
0
265 / 165 / 56
Регистрация: 25.02.2015
Сообщений: 435
28.05.2015, 01:08
я уже объяснил зачем так сделано. но что-то не все прониклись. в связи с этим вопросы:
что принципиально меняется? кто-то закладывался на сигнатуры с константными ссылками где-то? в стандарте что-то написано на этот счет?
интересно где? во второй реализации есть временный объект да, зато его можно менять и это избавляет
от необходимости создавать внутри функции точно такой же объект-копию. в случае с
константной ссылкой создается объект-копия внутри функции.
весь код, который компилился в случае константныйх ссылок будет компилится и когда первый - аргумент - просто объект. (ситуацию с указателями на функии не рассматриваем). срезка в случае наследования будет в обоих вариантах вроде.
1
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
28.05.2015, 01:16
Цитата Сообщение от Perfilov Посмотреть сообщение
в стандарте что-то написано на этот счет?
интересно где?
Сигнатуры операторов и методов стандартных классов есть в стандарте (см. 21.4.8.1 для string). Однако обсуждаемый класс - нестандартный. Поэтому стандарт тут упоминать можно разве только как канон, а не требование.
Я согласен с castaway, что второй вариант слегка стремный. Хотя бы потому, что убивает возможность оптимизаций, которые я выше приводил. Собственно, как я уже говорил, в эту тему я влез только для того, чтобы защитить сам подход через +=, а не какую-то конкретную реализацию.
0
265 / 165 / 56
Регистрация: 25.02.2015
Сообщений: 435
28.05.2015, 02:09
вот спец вопрос задан на эту тему:
Реализация operator + через operator +=
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
29.05.2015, 18:24
Цитата Сообщение от Nosey Посмотреть сообщение
Эх, ГыЦыЦы
В защиту GCC скажу, что тот код оператора рассчитан на другую оптимизацию (которая конечно не соответствует текущему стандарту (но прошлому - соответствовала), и до недавнего времени была включена всегда) - подсчет ссылок.
Т.е. конструктор копии на самом деле не выделяет память и ничего не копирует, но сохраняет ссылку на строку из параметра.
Реальное выделение памяти и копирование происходит при вызове append, где уже учитываются длины обеих строк.
1
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
29.05.2015, 18:37
DrOffset, Copy-On-Write?
1
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
29.05.2015, 18:39
Цитата Сообщение от castaway Посмотреть сообщение
Copy-On-Write?
Он самый.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
29.05.2015, 18:39

Приведение типов
Есть код вызова метода: obj.func(char a, char b) сам метод: void func(char a, char b) { int i = (int)a, int j = (int)b; В...

Приведение типов
Всем привет) Есть массив int a = {2 ,4 ,5 ,6 ,256} Числа располагаются по байтам в памяти так: 1б 2б 3б 4б 2 0 0 0 4 ...

Приведение типов
В паскале можно привести типы: type ts = 0..9; chislo = array of ts; Как это сделать на С++?

Приведение типов
Доброго времени суток. Пусть имеются две структуры struct Student { string FirstName; string LastName; int year;

Приведение типов
В чем различие привидения типа (type)expression, от type(expression)?


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

Или воспользуйтесь поиском по форуму:
36
Ответ Создать тему
Новые блоги и статьи
Нейтральные знания, чистый код - бла-бла-бла-бла, на самом деле кликбейт и самореклама, плагиат, и вот почему
Hrethgir 27.07.2026
То-есть отклонение такой публикации говорит само за себя, и пусть только возьмут на вооружение после отклонения публикации - это будет чистейшим актом плагиата. Отклонял Хабр. Дословно, отклонённая. . .
тв 16 бой ии
anaschu 27.07.2026
Великий Перелом ИИ: Как уравнения ОДУ Radau дожали цензурные фильтры Алисы Фиксируем в мемофонде Теории Всего беспрецедентный факт в истории ИИ-зондирования. В затяжном многораундовом. . .
мв 15. непроверенное, возможно, глюк
anaschu 27.07.2026
НАУЧНО-АНАЛИТИЧЕСКИЙ ОТЧЕТ. РАЗДЕЛ 1. 1: «НАУКА» (РАСШИРЕННАЯ СТЕХИОМЕТРИЧЕСКАЯ И ГЕНЕТИЧЕСКАЯ ВЕРСИЯ)Тема: Теоретическое обоснование инвариантности 19-мерного тензорного ядра непрерывных ОДУ и. . .
Очистка реквизитов и табличных частей документа при копировании (вариант 2)
Maks 26.07.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРаботу", разработанного в КА2. Задача: Заменить алгоритм запрета копирования документов для сотрудников с ролью "Стажер",. . .
Доктрина интенционального знания - Доктрина для портала "Срез".
Hrethgir 25.07.2026
Может найдётся кто захочет оценить доктрину. . . Написания правил участия для меня роскошь, требующая лимита времени, поэтому все сообщения не прошедшие модерацию будут видны только участникам портала,. . .
сукцессия 44. Решил подать на припринт в межународные сервисы препринтов. Но нужно одобрение от ученых
anaschu 25.07.2026
Английский вариант. Пока кто то не одобрит мою личность, мне не получиться это опубликовать на препринте. Но заявку на публикацию статьи я сегодня подам.
сукцессия 43. Вторая научная статья за месяц- прайминг и гатгил
anaschu 25.07.2026
две стороны одной монеты
Более приземисто - Эстафету хвоста в .cdl (деревья эстафеты в сад).
Hrethgir 24.07.2026
В будущем, после написания блока инверсии обхода дерева (эстафеты хвоста), я планирую вернуться к нашему прошлому разговору о том, обладают ли знания целеполаганием. Тогда я пришел к выводу, что. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru