RXL
|
|
« : 21-12-2010 07:05 » |
|
Мне требуется конвертировать борландовский AnsiString (аналог Dephi String) и std::string между собой. Понятное дело, внедряться в классы я не могу. Операторы "+" и "+=" перегрузить удалось и они работают. Преобразование типов сделал на функциях, но хотелось бы сократить запись. Фактически преобразование делается через внутренний указатель const char *: AnsiString s1 = "111111"; std::string s2 = s1.c_str();
std::string s3 = "22222222"; AnsiString s4 = s3.c_str(); Конструктор копирования вне класса невозможен. А возможен ли оператор "=" вне класса? Добавлено через 7 минут и 32 секунды:Пробую: 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 »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #1 : 21-12-2010 07:26 » |
|
вроде и нельзя, но возвращаться должна ссылка (а ещё лучше - void ИМХО)
а почему бы свою оболочку не написать, чем раскидывать функции в глобальной области ?
|
|
« Последнее редактирование: 21-12-2010 07:31 от Алексей1153++ »
|
Записан
|
|
|
|
RXL
|
|
« Ответ #2 : 21-12-2010 09:01 » |
|
Леш, ссылку возвращать из оператора не обязательно. Более того, ссылки не в контексте объекта приводят к проблемам.
Оболочку к чему? Есть большой набор всяких API: STL, борландовский, сторонние под борланд. Они пользуются имеющимися объектами. Как я тут примощу свои обертки?...
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #3 : 21-12-2010 09:08 » |
|
RXL, оператор = вне класса, конечно, возможен. Мне только непонятно, почему у тебя 2 аргумента этого оператора при наличии результата?.. Ведь это три значения, увязанные в одно выражение, а: Мне, например, понятно: operator=(x, y); // или y.operator=(x);
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #4 : 21-12-2010 09:38 » |
|
Леш, ссылку возвращать из оператора не обязательно.
я и говорю - лучше void
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #5 : 21-12-2010 12:16 » |
|
Dimka, заработался я малость... 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
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #6 : 21-12-2010 15:24 » |
|
RXL, а вроде и правда не может быть оператора = не члена класса... Странно, меня удивило.
Вот мне тут специалист по C++ подсказывает, что оператор = по умолчанию для простых типов компилятор реализует не как вызов функции operator=, поэтому при компиляции разных объектных файлов могут возникать конфликты. В одном случае компилятор может не знать про то, что есть особая реализация оператора, и формирует код без вызова функции, а на этапе линковки факт перегрузки оператора станет известным, но уже ничего нельзя будет сделать.
Поэтому перегрузка оператора = имеет смысл только для определяемых пользователем типов данных (классов), и нет смысла делать оператор не член.
|
|
« Последнее редактирование: 21-12-2010 15:36 от Dimka »
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Антон (LogRus)
|
|
« Ответ #7 : 21-12-2010 18:24 » |
|
RXL, перегрузи оператор << то же удобная запись получается struct A { int x; }; struct B { int y; }; void operator<<(A & lhs, const B & rhs) { lhs.x = rhs.y; } void operator<<(B & lhs, const A & rhs) { lhs.y = rhs.x; } int main() { A a; a.x = 1; B b; b.y = 2; a << b; std::cout << b.y << "\n"; a.x = 3; b << a; std::cout << b.y << "\n"; return 0; }
|
|
|
Записан
|
Странно всё это....
|
|
|
RXL
|
|
« Ответ #8 : 21-12-2010 19:15 » |
|
Антон, дык, попробуй "=" или "тип"...
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Антон (LogRus)
|
|
« Ответ #9 : 22-12-2010 05:09 » |
|
RXL, что-то не получается поэтому и предложил <<
|
|
|
Записан
|
Странно всё это....
|
|
|
RXL
|
|
« Ответ #10 : 22-12-2010 06:32 » |
|
Хитер Так потом код будет непонятный...
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Антон (LogRus)
|
|
« Ответ #11 : 22-12-2010 06:36 » |
|
RXL, ну отчего же, по мне так вполне понятный можно через такой оператор сделать за одно конкатенацию строк
|
|
|
Записан
|
Странно всё это....
|
|
|
RXL
|
|
« Ответ #12 : 22-12-2010 06:40 » |
|
Объединение я сделал классически - через "+".
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Антон (LogRus)
|
|
« Ответ #13 : 22-12-2010 06:55 » |
|
есть кстати интересные перегрузки (увидел тут недавно) унарный + возвращаяет размер строки унарный ~ возвращяеет c_str
код после этого выглядит гораздо лучше, если приходится часто использовать string.size и string.c_str
|
|
|
Записан
|
Странно всё это....
|
|
|
RXL
|
|
« Ответ #14 : 22-12-2010 19:38 » |
|
Насчет "~" - хорошая идея. Надо будет принять на вооружение. Во всяком случае, побитовая инверсия строки - нонсенс и сразу привлечет внимание.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #15 : 22-12-2010 21:21 » |
|
Не думаю, что замена таких методов, как определение длины строки или преобразования, на унарные операторы - это совсем уж хорошая идея. Как говорил Дейкстра, язык программирования формирует мышление программиста. Синтаксическое облегчение таких операций может привести к злоупотреблениям, из-за которых ухудшится производительность, поскольку вызовы таких операций будут гораздо проще создания временных переменных.
Так что сильно зависит от решаемой задачи.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
RXL
|
|
« Ответ #16 : 22-12-2010 23:09 » |
|
Дим, в данном случае нужна взаимная конверсия между двумя строковыми типами. Функции - менее удобно из-за закрывающей скобки.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Антон (LogRus)
|
|
« Ответ #17 : 23-12-2010 04:16 » |
|
Не думаю, что замена таких методов, как определение длины строки или преобразования, на унарные операторы - это совсем уж хорошая идея. Как говорил Дейкстра, язык программирования формирует мышление программиста. Синтаксическое облегчение таких операций может привести к злоупотреблениям, из-за которых ухудшится производительность, поскольку вызовы таких операций будут гораздо проще создания временных переменных.
Так что сильно зависит от решаемой задачи.
невижу связи между унарными операторами, высказванием Дейкстры и проблеми с производительностью
|
|
|
Записан
|
Странно всё это....
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #18 : 23-12-2010 07:55 » |
|
невижу связи между унарными операторами, высказванием Дейкстры и проблеми с производительностью ...бывает.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Антон (LogRus)
|
|
« Ответ #19 : 23-12-2010 08:21 » |
|
ничего не бывает, ты приведи примеры как унарный оператор в данном случае повлияет на производительность
|
|
|
Записан
|
Странно всё это....
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #20 : 23-12-2010 11:23 » |
|
Антон (LogRus), я не сказал, что унарный оператор влияет на производительность. Я сказал, что программист, привыкший к этим унарным операторам, может забыть о том, какие по ресурсоёмкости операции за ними стоят. Красивая запись не означает безусловно эффективный код.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Антон (LogRus)
|
|
« Ответ #21 : 23-12-2010 12:09 » |
|
ну, это можно всегда забыть, хоть оператор, хоть new, хоть методы и функции в имени метода обычно не пишут - Внимание: прожорливый до памяти метод. но с тем, что с операторами обжечься проще я согласен.
|
|
|
Записан
|
Странно всё это....
|
|
|
RXL
|
|
« Ответ #22 : 24-12-2010 09:54 » |
|
Дошел до отладки и началась Ж... AnsiString toAS(const std::string &stdStr) { return AnsiString(stdStr.c_str()); } Вроде бы, чему тут сбоить? Но один из нескольких тысяч вызовов приводит к исключению и, что противно, отладчик не показывает аргумента функции (видимо сбой происходит в момент return). Может AnsiString(const char *) просто сохраняет в себе указатель на строку? Пробовал сделать двойную прослойку: AnsiString toAS(const std::string &stdStr) { return AnsiString(AnsiString(stdStr.c_str())); } Конструктор AnsiString(const AnsiString &) должен копировать строку. Но и это не помогает. Если задать параметром функции не ссылку, а объект, то программа работает, но тормозит (раз в 100 медленней!).
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #23 : 24-12-2010 10:01 » |
|
void toAS(const std::string &stdStr, AnsiString& dest) { dest=stdStr.c_str(); }
а так должно работать, тут нет никаких хитростей
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #24 : 24-12-2010 10:07 » |
|
Лажанулся и в одном месте вернул ссылку на локальный объект. Исправил и снова тормоза. Думаю, что придется отказаться от std::string в пользу "родного" AnsiString.
Добавлено через 1 минуту и 5 секунд: Леш, это не практично совершенно.
|
|
« Последнее редактирование: 24-12-2010 10:08 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #25 : 24-12-2010 10:23 » |
|
Леш, это не практично совершенно.
в плане скорости и безошибочности - это практичнее не придумаешь
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #26 : 24-12-2010 11:09 » |
|
Наиболее частое применение строки - присвоение, конкатенация и передача параметром. Ни в одном из этих случаем данная функция не применима. В присвоении не применима по причине того, что в BCB есть члены-свойства (не мемберы C++!), которые есть суть скрытые вызовы методов класса для присвоения и чтения. В общем, перешел на AnsiString. Компилятору полегчало и мне тоже (времени до НГ совсем не осталось). А тормоза оказались в другом: ошибка копи-паста. class A; class B; typedef map<int, A> mapA; typedef map<int, B> mapB; class A { public: mapB items; }; class B { public: int x; }; // .... mapA a; for (mapA::iterator ita = a.begin(); ita != a.end(); ita++) for (mapB::iterator itb = ita->second.items.begin(); ita != ita->second.items.end(); ita++) // чтение itb->second.x
В строке 24 две ошибки. Сравнение итераторов разных типов допустимо?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
npak
|
|
« Ответ #27 : 24-12-2010 11:36 » |
|
Рома, ты зачем во втором for сравниваешь ita с ita->second.items.end() и до кучи ещё инкрементируешь ita? ИМХО, должно быть for (mapB::iterator itb = ita->second.items.begin(); itb != ita->second.items.end(); itb++) Добавлено через 4 минуты и 50 секунд:Пользоваться Борландовскими тулами - ты герой. Чем тебя Visual Studio не устраивает?
|
|
« Последнее редактирование: 24-12-2010 11:41 от npak »
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #28 : 24-12-2010 12:02 » |
|
npak, наверно, стремительное приближение НГ и лучшее знание BC++B по сравнению с VC++ В таких условиях меня бы тоже VC++ не устроило.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
RXL
|
|
« Ответ #29 : 24-12-2010 12:59 » |
|
Коль, я ошибку я специально привел - такие вот сравнения компилятор пропускает и не ругается.
А на счет BCB6 - так проект в нем написан. Его лет 10 пишут. Последние 4 года это мой крест.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
|