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

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

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

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

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

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

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

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

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


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

есть кстати интересные перегрузки (увидел тут недавно)
унарный + возвращаяет размер строки
унарный ~ возвращяеет 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