Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: AnsiString и std::string. Оператор присваивания вне класса. (не дружественный)  (Прочитано 40648 раз)
0 Пользователей и 1 Гость смотрят эту тему.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« : 21-12-2010 07:05 » 

Мне требуется конвертировать борландовский AnsiString (аналог Dephi String) и std::string между собой. Понятное дело, внедряться в классы я не могу.

Операторы "+" и "+=" перегрузить удалось и они работают. Преобразование типов сделал на функциях, но хотелось бы сократить запись.
Фактически преобразование делается через внутренний указатель const char *:

Код: (C++)
AnsiString s1 = "111111";
std::string s2 = s1.c_str();

std::string s3 = "22222222";
AnsiString s4 = s3.c_str();

Конструктор копирования вне класса невозможен. А возможен ли оператор "=" вне класса?


Добавлено через 7 минут и 32 секунды:
Пробую:

Код: (C++)
AnsiString operator= (const AnsiString &bcbStr, const std::string &stdStr);
std::string operator= (const std::string &stdStr, const AnsiString &bcbStr);

E2239 'operator =(const AnsiString &,const _STL::string &)' must be a member function
E2239 'operator =(const _STL::string &,const AnsiString &)' must be a member function
« Последнее редактирование: 21-12-2010 07:15 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 21-12-2010 07:26 » 

вроде и нельзя, но возвращаться должна ссылка (а ещё лучше - void ИМХО)

а почему бы свою оболочку не написать, чем раскидывать функции в глобальной области ?
« Последнее редактирование: 21-12-2010 07:31 от Алексей1153++ » Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 21-12-2010 09:01 » 

Леш, ссылку возвращать из оператора не обязательно. Более того, ссылки не в контексте объекта приводят к проблемам.

Оболочку к чему? Есть большой набор всяких API: STL, борландовский, сторонние под борланд. Они пользуются имеющимися объектами. Как я тут примощу свои обертки?...
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 21-12-2010 09:08 » 

RXL, оператор = вне класса, конечно, возможен. Мне только непонятно, почему у тебя 2 аргумента этого оператора при наличии результата?.. Ведь это три значения, увязанные в одно выражение, а:
Код:
y = x;
Мне, например, понятно:
Код:
operator=(x, y); // или
y.operator=(x);
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 21-12-2010 09:38 » 

Леш, ссылку возвращать из оператора не обязательно.
я и говорю - лучше void Улыбаюсь
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 21-12-2010 12:16 » 

Dimka, заработался я малость...


Код: (Text) с++
AnsiString operator= (const std::string &stdStr)
{
    return AnsiString(stdStr.c_str());
}

std::string operator= (const AnsiString &bcbStr)
{
    return std::string(bcbStr.c_str());
}

[C++ Error] string.cpp(27): E2239 'operator =(const _STL::string &)' must be a member function
[C++ Error] string.cpp(32): E2239 'operator =(const AnsiString &)' must be a member function
« Последнее редактирование: 21-12-2010 12:18 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 21-12-2010 15:24 » 

RXL, а вроде и правда не может быть оператора = не члена класса... Странно, меня удивило.

Вот мне тут специалист по C++ подсказывает, что оператор = по умолчанию для простых типов компилятор реализует не как вызов функции operator=, поэтому при компиляции разных объектных файлов могут возникать конфликты. В одном случае компилятор может не знать про то, что есть особая реализация оператора, и формирует код без вызова функции, а на этапе линковки факт перегрузки оператора станет известным, но уже ничего нельзя будет сделать.

Поэтому перегрузка оператора = имеет смысл только для определяемых пользователем типов данных (классов), и нет смысла делать оператор не член.
« Последнее редактирование: 21-12-2010 15:36 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #7 : 21-12-2010 18:24 » 

RXL, перегрузи оператор << Улыбаюсь то же удобная запись получается
Код: (C++)
  1. struct A
  2. {
  3.     int x;
  4. };
  5.  
  6. struct B
  7. {
  8.     int y;
  9. };
  10.  
  11. void operator<<(A & lhs, const B & rhs)
  12. {
  13.     lhs.x = rhs.y;
  14. }
  15.  
  16. void operator<<(B & lhs, const A & rhs)
  17. {
  18.     lhs.y = rhs.x;
  19. }
  20.  
  21. int main()
  22. {
  23.     A a;
  24.     a.x = 1;
  25.     B b;
  26.     b.y = 2;
  27.     a << b;
  28.     std::cout << b.y << "\n";
  29.  
  30.     a.x = 3;
  31.     b << a;
  32.     std::cout << b.y << "\n";
  33.  
  34.     return 0;
  35. }
Записан

Странно всё это....
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 21-12-2010 19:15 » 

Антон, дык, попробуй "=" или "тип"...
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #9 : 22-12-2010 05:09 » 

RXL, что-то не получается Улыбаюсь
поэтому и предложил <<
Записан

Странно всё это....
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 22-12-2010 06:32 » 

Хитер Улыбаюсь
Так потом код будет непонятный...
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #11 : 22-12-2010 06:36 » new

RXL, ну отчего же, по мне так вполне понятный
можно через такой оператор сделать за одно конкатенацию строк Улыбаюсь
Записан

Странно всё это....
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 22-12-2010 06:40 » 

Объединение я сделал классически - через "+".
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #13 : 22-12-2010 06:55 » 

есть кстати интересные перегрузки (увидел тут недавно)
унарный + возвращаяет размер строки
унарный ~ возвращяеет c_str

код после этого выглядит гораздо лучше, если приходится часто использовать string.size и string.c_str
Записан

Странно всё это....
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #14 : 22-12-2010 19:38 » 

Насчет "~" - хорошая идея. Надо будет принять на вооружение. Во всяком случае, побитовая инверсия строки - нонсенс и сразу привлечет внимание.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 22-12-2010 21:21 » 

Не думаю, что замена таких методов, как определение длины строки или преобразования, на унарные операторы - это совсем уж хорошая идея. Как говорил Дейкстра, язык программирования формирует мышление программиста. Синтаксическое облегчение таких операций может привести к злоупотреблениям, из-за которых ухудшится производительность, поскольку вызовы таких операций будут гораздо проще создания временных переменных.

Так что сильно зависит от решаемой задачи.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 22-12-2010 23:09 » 

Дим, в данном случае нужна взаимная конверсия между двумя строковыми типами. Функции - менее удобно из-за закрывающей скобки.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #17 : 23-12-2010 04:16 » 

Не думаю, что замена таких методов, как определение длины строки или преобразования, на унарные операторы - это совсем уж хорошая идея. Как говорил Дейкстра, язык программирования формирует мышление программиста. Синтаксическое облегчение таких операций может привести к злоупотреблениям, из-за которых ухудшится производительность, поскольку вызовы таких операций будут гораздо проще создания временных переменных.

Так что сильно зависит от решаемой задачи.

невижу связи между унарными операторами, высказванием Дейкстры и проблеми с производительностью
Записан

Странно всё это....
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #18 : 23-12-2010 07:55 » 

Цитата: LogRus
невижу связи между унарными операторами, высказванием Дейкстры и проблеми с производительностью
...бывает.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #19 : 23-12-2010 08:21 » 

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

Странно всё это....
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #20 : 23-12-2010 11:23 » 

Антон (LogRus), я не сказал, что унарный оператор влияет на производительность. Я сказал, что программист, привыкший к этим унарным операторам, может забыть о том, какие по ресурсоёмкости операции за ними стоят. Красивая запись не означает безусловно эффективный код.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #21 : 23-12-2010 12:09 » 

ну, это можно всегда забыть, хоть оператор, хоть new, хоть методы и функции
в имени метода обычно не пишут - Внимание: прожорливый до памяти метод.
но с тем, что с операторами обжечься проще я согласен.
Записан

Странно всё это....
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #22 : 24-12-2010 09:54 » 

Дошел до отладки и началась Ж...

Код: (Text) с++
AnsiString toAS(const std::string &stdStr)
{
    return AnsiString(stdStr.c_str());
}

Вроде бы, чему тут сбоить? Но один из нескольких тысяч вызовов приводит к исключению и, что противно, отладчик не показывает аргумента функции (видимо сбой происходит в момент return).

Может AnsiString(const char *) просто сохраняет в себе указатель на строку? Пробовал сделать двойную прослойку:

Код: (Text) с++
AnsiString toAS(const std::string &stdStr)
{
    return AnsiString(AnsiString(stdStr.c_str()));
}

Конструктор AnsiString(const AnsiString &) должен копировать строку. Но и это не помогает.

Если задать параметром функции не ссылку, а объект, то программа работает, но тормозит (раз в 100 медленней!).
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #23 : 24-12-2010 10:01 » 

Код:
void toAS(const std::string &stdStr, AnsiString& dest)
{
    dest=stdStr.c_str();
}

а так должно работать, тут нет никаких хитростей
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #24 : 24-12-2010 10:07 » 

Лажанулся и в одном месте вернул ссылку на локальный объект. Исправил и снова тормоза.
Думаю, что придется отказаться от std::string в пользу "родного" AnsiString.

Добавлено через 1 минуту и 5 секунд:
Леш, это не практично совершенно.
« Последнее редактирование: 24-12-2010 10:08 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #25 : 24-12-2010 10:23 » 

Леш, это не практично совершенно.
в плане скорости и безошибочности - это практичнее не придумаешь Улыбаюсь
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #26 : 24-12-2010 11:09 » 

Наиболее частое применение строки - присвоение, конкатенация и передача параметром. Ни в одном из этих случаем данная функция не применима. В присвоении не применима по причине того, что в BCB есть члены-свойства (не мемберы C++!), которые есть суть скрытые вызовы методов класса для присвоения и чтения.

В общем, перешел на AnsiString. Компилятору полегчало и мне тоже (времени до НГ совсем не осталось).

А тормоза оказались в другом: ошибка копи-паста.

Код: (C++)
  1. class A;
  2. class B;
  3.  
  4. typedef map<int, A> mapA;
  5. typedef map<int, B> mapB;
  6.  
  7. class A
  8. {
  9. public:
  10.   mapB items;
  11. };
  12.  
  13. class B
  14. {
  15. public:
  16.   int x;
  17. };
  18.  
  19. // ....
  20.  
  21. mapA a;
  22.  
  23. for (mapA::iterator ita = a.begin(); ita != a.end(); ita++)
  24.   for (mapB::iterator itb = ita->second.items.begin(); ita != ita->second.items.end(); ita++)
  25.     // чтение itb->second.x

В строке 24 две ошибки. Сравнение итераторов разных типов допустимо?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #27 : 24-12-2010 11:36 » 

Рома, ты зачем во втором for сравниваешь ita с ita->second.items.end() и до кучи ещё инкрементируешь ita?
ИМХО, должно быть
Код: (C++)
for (mapB::iterator itb = ita->second.items.begin(); itb != ita->second.items.end(); itb++)

Добавлено через 4 минуты и 50 секунд:
Пользоваться Борландовскими тулами - ты герой. Чем тебя Visual Studio не устраивает?
« Последнее редактирование: 24-12-2010 11:41 от npak » Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #28 : 24-12-2010 12:02 » 

npak, наверно, стремительное приближение НГ и лучшее знание BC++B по сравнению с VC++ Улыбаюсь В таких условиях меня бы тоже VC++ не устроило.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #29 : 24-12-2010 12:59 » 

Коль, я ошибку я специально привел - такие вот сравнения компилятор пропускает и не ругается.

А на счет BCB6 - так проект в нем написан. Его лет 10 пишут. Последние 4 года это мой крест.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines