Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Как не надо писать код |
Автор: Ignat 18.3.2006, 06:52 |
Это не вопрос, а скорее крик души. Месяца два с половиной, в свободное от работы время, мучаю проект. И вот, похоже, настал конец терпению. Чем больше разбираюсь в этом коде, тем больше хренею (другое слово не подберешь). Яркий пример того, как не надо писать. По порядку: 1. Видимо, все знание автора об отличиях С от С++ сводится к наличию единственного класса, единственный экземпляр которого инстанцирован в структуру(!), что само по себе нормально, за исключением того вопроса на фига это там было нужно, для меня так и осталось загадкой. 2. Догадайтесь как обстоят дела с выделением памяти? Именно, незабвенный malloc. По некоторому стечению обстоятельств, функций free я обнаружил меньше :\ 3. С потоками такая же напряженнка, как и с выделением new. #include <stdio.h> и точка, нафиг нам стримы? 4. Собственно от чего я сегодня опупел - static-функции вне класса. Честно сознаюсь, никогда так не извращался, посему тот факт, что я её фиг увижу за пределами единицы трансляции поверг меня в уныние. Нэймспейсы, видимо, отменили специально для "аффтара". Для чего это вообще делалось, так и не понял. 5. Об RTTI тоже автору ничего не известно. Следствие - около полусотни варнингов об опасном присваивании при компиляции. 6. Никакого намека на STL. Я, конечно, рад что в программе так классно реализованы операции с массивами, массивами указателей, массивами указателей на указатели, указателями на массивы указателей на указатели. Но, блин, чтоб выбрать элемент по имени, мне перебор прикажете делать? 7. Отдельная песня - это имена переменных и функций. Ни один шпион не догадается. Если комменты не прочитает. Вот только комменты в .h, а нужно работать с реализацией. Вот как вы думаете, зачем нужен следующий код: void stdexitcls(char s, float pt, float sl, int bth) { sexord=1; sexi=s; sexpt=ptt(pt); sexsl=ptt(sl); sexbrs=bth; }; Вот я тоже не телепат. Смотрим объявление, например: char sexi; // standard exit id Вот ведь, блин, а я уж было подумал... Оказывается sexi и отношения к сексу не имеет, разве что церебральному. 8. Вернёмся к классу. Убедившись, что править что-то в этом коде сродни подвигам Геракла, вместе взятым есессно, решил воспользоваться одним из базовых столпов ООП - полиморфизмом. Унаследовал класс, написал свою реализацию нужных мне методов, а вот не переопределенные методы вдруг перестали работать. Удивительно? А мне нет. Те члены класса, которыми они пользуются были объявлены в приватной секции, а совсем не protected. Блин, по скромной оценке кода больше тысячи строк... Как дальше с этим работать просто загадка тысячелетия. Но если назвался груздем... Были ли у вас такие подлянки? Как мне дальше разгребать? |
Автор: Ignat 18.3.2006, 12:38 | ||
Ну это я сильно поскромничал, 1000 строк - это только та часть, с которой я работаю, даже, наверное 1500-2000 будет точнее, остальное было скомпилено в либы и благопулучно забыто. Общее количество строк в проекте (только .cpp и .с файлы, без учета хидеров) 14 225. Если это дело реверсить, то придется поднимать всё. А мой неокрепший организм такого мазохизма не вынесет... Фунция, на которой я споткнулся в п.4 принимает 13 параметров. Здесь я натыкался на switch из 25-27 вариантов, хотя ИМХО это не страшно. Если задача отправить мессагу об ошибке, то самый приемлимый вариант. |
Автор: Mayk 18.3.2006, 13:25 | ||||
Пинать. Аффатру явно забыли сообщить что имена переменных можно делать из >6 символов и читабельными
+1 Верни это на ту помойку из которой..... на родину вообщем.
а как же map<ErrorID, string> и exception::what()? |
Автор: Ignat 18.3.2006, 13:30 |
Посыпаю голову ![]() ЗЫ кстати, exception отсутствует, зато есть глобальная функция FatalError. С однозначной реакцией умереть нафик, даже если это не нужно. |
Автор: DeadSoul 18.3.2006, 13:37 |
![]() |
Автор: Athlon 18.3.2006, 20:35 |
если ты разгребаешь opensource код, то это типичная ситуация ![]() а вообще, хочется всем пожелать побольше внимания уделять комментариям !!! |
Автор: Earnest 20.3.2006, 18:06 |
Что делать: если исходный код работает правильно, лучше его не трогать, а написать свой фасад или адаптер. Причем сначала спроектировать интерфейс, не глядя в это г., а потом попробовать реализовать его. Если неправильно - забыть про него совсем и переписать. |
Автор: S.A.P. 20.3.2006, 18:20 |
Часто на работе сталкиваюсь с такими комментариями одного товарища: 1. // Пока не конец. 2. // В массив. 3. // Составляем запрос. 4. // Всё... и т.д. И ни одного толкового комментария. Лучше вобще их не писать тогда ![]() |
Автор: Ignat 20.3.2006, 18:24 |
Работает правильно. Вот это я и делаю, но в процессе приходится выяснять логику, тут и начинается свистопляска. Очень ценное замечание. Спасибо, так и поступлю. ![]() 14 тыс строк? |
Автор: Earnest 20.3.2006, 18:58 | ||
Не факт, что в результате будет столько же. Но поскольку то, конечно, лучше не трогать, не смотря на
А кому сейчас легко? ![]() ![]() ![]() |
Автор: DeadSoul 20.3.2006, 22:45 | ||
Earnest, а если надо что-то изменить в поведение этой функции? А рефакторинг провести нереально? |
Автор: chipset 21.3.2006, 01:23 | ||
Мы живем не в идеальном мире, рефакторинг нужно проводить только когда его нужно проводить а не просто потому-что так хочеться (ну если конечно, у тебя это не хобби) |
Автор: UnixBeginner 21.3.2006, 13:19 |
Есть прикольная книженция о том, как желательно оформлять исходный код программ. Вот только не нашел как тут файлик присоеденить, так что если кому нужна (она небольшая *.doc), могу скинуть или выложить где скажите ![]() |
Автор: np9mi7 21.3.2006, 13:35 | ||||
12) Hard Code (сообщения, числа и.т.д.); 13) Non Const Global Variable (просто бесит что вместо стека используется глобальная свалка - функциональное программирование); 14) Memory Leak (только стратегия владения и сборка мусора); 15) Native Implementation Dependence (бесит, когда пишут код зависимый от реализации); |
Автор: bilbobagginz 21.3.2006, 13:44 |
насчет всего того что код предыдущего кодера иногда писан через одно место: вопрос какая задача стояла у программиста предыдущего кодa. Oбычно интересный проект - пайлот, когда заказчик еще сам не знает чего надо досконально, и описывает задачу в процессе реализации. также возможны подводные камни которые без опыта обнаружатся тоже в процессе реализации. можно не взять такой заказ, а можно взять. когда берешь, имеет место быть шанс плохого дезайна. есть конечно тривиальные задачи, которые не нужно "разрабатывать" - взял шаблон и шаблонь. но не всегда. но ногами писАть, согласен - нехорошо! |
Автор: UnrealMan 30.3.2006, 14:26 | ||
А чем собс-но плох malloc? В случае, когда используются нетривиальные объекты (с конструктором, деструктором), и требуется перевыделение памяти с сохранением данных (realloc), использование new и delete – явно не самое удачное решение. |
Автор: likehood 30.3.2006, 17:38 | ||
А как ты собрался вызывать коструктор из маллока? ![]() Хотя, конечно, в данном случае new и delete не особо нужны - классов то все равно нет. |
Автор: DeadSoul 30.3.2006, 21:57 | ||
1. (Как сказали выше) Ничего не знает про конструкторы\деструкторы 2. Для malloca нет smart pointer-ов
Самое лучшее решен ие в таком случае - std::vector, но никак не realloc |
Автор: UnrealMan 31.3.2006, 09:13 | ||||||||||
Ясное дело, конструктор вызывается отдельно.
И что? Самому сложно добавить их вызов?
Не велика потеря. При желании можно написать свои.
Чем же оно самое лучшее? Быcтрей работает что ли (во всех ситуациях)? |
Автор: likehood 31.3.2006, 10:31 | ||||
Что??? Явный вызов конструктора по указателю? Ты на каком языке пишешь? Да ты что, это же мое любимое занятие - делать работу за компилятора. ![]() А причем тут умные указатели? Для них просто перегружают некоторые операции, но совсем не обязательно перегружать new и delete.
Лучшее - не значит самое быстрое. А то бы все писали на Си и Асме. |
Автор: UnrealMan 31.3.2006, 16:27 | ||||||||||
Ну, да. А что тут, собс-но, смущает?
Ну, макросы ещё вроде бы никто не отменял:
Правда, чтобы эта штуковина заработала внутри шаблонов, придётся ещё повозиться :-)
В некоторых ситуациях быстрота существенна. |
Автор: DeadSoul 31.3.2006, 23:53 | ||||
Велосепидисты вперед!
Еще раз вперед А что знают макросы про области видимости и пространства имен? |
Автор: UnrealMan 1.4.2006, 10:00 | ||
То же, что и new :-) Ну, и? Это типа повод использовать везде и всюду std::vector? Я-то, в общем-то, не выдвигаю здесь тезис в духе «malloc рулит, всё остальное голимый отстой», а только спрашиваю, почему само по себе использование malloc (независимо от того, какая задача решается) вызывает этакое презрение. |
Автор: DeadSoul 1.4.2006, 11:26 | ||
Потому, что для new все уже написано. |
Автор: UnrealMan 1.4.2006, 18:02 | ||
Потому, что предрассудки всё это :-) |
Автор: DeadSoul 1.4.2006, 18:37 | ||
Это не предрассудки. Это деньги. За последний год я ни разу не написал delete или delete[]. Умные указатели\STL рулят |
Автор: UnrealMan 2.4.2006, 09:41 |
Примитивно это как-то – выискивать некий самый лучший способ на все случаи жизни. Всё зависит от требований задачи. И вот уж как не надо писать код, так это без учёта этих самых требований, руководствуясь только лишь мыслью «а у меня уже есть самый-самый крутой способ, я буду с превеликим благоговением молиться на него и использовать везде во всех своих программах». |
Автор: likehood 2.4.2006, 10:19 | ||||
Да вот как раз не выискивать лучшие способы примитивно, только не на все случаи жизни, а на большую их часть. Если меня устраивает быстродействие new/delete, то почему я должет отказываться от них? Но в любом случае malloc - не лучшее решение, правильнее будет перегрузить new/delete. В любом случае, для использования malloc должны быть очень веские причины и вряд ли в том г. про которое говорил Ignat они были (кроме плохого знания С++). P.S. 2UnrealMan А на счет явного вызова конструктора - признаю, не знал. Просто никогда не доводилось пользоваться. Решил проверить первым попавшимся под руку компилером - это был 6-й Билдер. Билдер дал по рукам. После твоего поста:
попробовал еще раз - на этот раз в VC6. Все прошло в лучшем виде. Правду говорят - Билдер это зло. |
Автор: UnrealMan 2.4.2006, 11:48 | ||||||||
Отказываться от new и delete я и не призываю. Да и к быстродействию самих по себе new/delete я никаких претензий не имею – собс-но, если я чего не путаю, они вызывают те же malloc и free, а потому по скорости работают одинаково. Хотя есть и функции, которые работают пошустрей, например, AllocMemory и FreeMemory (bhsupp.dll). Однако ж я не вижу причин полного отказа от malloc.
Обоснования этой правильности?
Ну прям очень. Один и тот же результат (в отношении тривиальных объектов без конструкторов), но new всё равно лучше! :-) В это надо просто уверовать...
А как ты в builder'е пробовал-то вызывать конструктор? Так: pointer->Class() или так: pointer->Class::Class() ? |
Автор: likehood 2.4.2006, 15:52 | ||||
На практике все же new и delete работают насколько медленнее. Можно для проверки написать тест, но в любом случае эта разница будет совсем небольшая. Здесь все зависит от компилятора. А я не вижу причин его использования. Если конечно мы пишем на С++, а не на С. Imho, это разговор в никуда - как всегда договоримся, что malloc рулит (что надо еще доказать), но только в 0,0001% случаях, а в остальном использование malloc'а - пережиток времен С. В итоге и те и другие будут правы, а кто выделял память malloc'ом так и будут это делать. Пора тему закрывать.
Да и так и эдак - Builder не знает метода Class(). В VC6 второй вызов работает как надо, можно даже не через указатель а напрямую. Но все это imho нужно не более, чем какой-нибудь const_cast. Кто-нить им хоть раз пользовался? |
Автор: Daevaorn 2.4.2006, 19:55 | ||||
Ну вы блин даете. Кто же так конструктор класса вызывает, а? Где это так написано?
Если vc компилит это ещё не значит что правильно. ![]() |
Автор: UnrealMan 3.4.2006, 10:56 | ||||
Зато есть большая разница в скорости (десятки раз) выделения разных объёмов памяти (так сказать, камешек в огород std::). Причём вся эта разница красуется на интервале малых объёмов (где-то до 1кБ).
:-) Дык, эт я методом тыка нашёл сей способ :-) Впрочем, я ожидал, что он может оказаться непереносимым. Кстати, как этому void *operator new(size_t, void *) соответствующий delete прописать? (а то мой компилятор ругается, а я уже не помню, как это дело улаживается) |
Автор: Daevaorn 3.4.2006, 18:47 | ||||
А он не нужен ![]()
|
Автор: UnrealMan 4.4.2006, 09:46 | ||||
Да вроде как желателен:
MSVC++6.0: warning C4291: 'void *__cdecl operator new(unsigned int,void *)' : no matching operator delete found; memory will not be freed if initialization throws an exception |
Автор: Earnest 4.4.2006, 18:17 |
Для каждой формы new (т.е. набора дополнительных аргументов) должна быть соответствующая форма delete (c тем же набором дополнительных аргументов). Для того редкого случая, когда исключение будет возбуждено сразу после благополучного выделения памяти (т.е. в конструкторе). Что, собственно, и написано в предупреждении. Странно, что компилятор не предоставляет стандартный размещающий delete (тогда как размещающий new есть). Возможно, это "особенности" VC 6. Но теоретически никто не мешает написать размещающий delete (он просто ничего не делает). Или просто забить на предупреждение (отклбючив его, чтобы не травмировать психику). ![]() |
Автор: ManiaK 10.4.2006, 13:07 | ||
Что-то какой-то жёсткий флуд пошёл, а ведь так забавно всё начиналось... ![]() Ignat, я, видимо, в этих вопросах избалован больше ![]()
Я бы поправил - глобальное переопределение. Переопределение этих операторов в каком-либо классе для меня даже приятно ![]() А вот это - да. Плохо, значит, продумано, раз такие функции приходится создавать. |
Автор: UnrealMan 11.4.2006, 14:42 | ||||
Ага, CreateWindowEx в топку: она юзает 12 параметров :-)
Вопрос был в том, как её правильно прописать (чтоб предупреждение убралось). |
Автор: Ignat 11.4.2006, 14:51 |
Ага... Именно в топку. Значительная часть виндового апи была унаследована от 16-битных приложений и оставлена для совместимости. Правда, вышеупомяннутая функция к ним не относится. Но почему передача параметров не была организована структурой - не понятно. |
Автор: Hose 11.4.2006, 15:36 |
Ох задело не удержался. На мой взгляд людям, которые без супер-пупер везких причин используют такие пережитки прошлого, как malloc(), а уж тем более явно вызывают конструктор класса, необходимо как можно скорее прижечь раскаленной качергой то место, которое у нех почему-то чешется. Я считаю, что если ты один делаешь программу для себя, то можешь хоть всю ее из макросов сделать в одном .cpp файле, не написав ни одного коментария. Но если ты пишешь программу не один, если ее объем достаточно большой, если твой код в будущем кому-то придется использовать, так буть добр действуй по общепринятым правилам. А теперь по теме. Лично меня больше всего бесит в чужом коде это псевдо крутые программерские фишки типа макросов или жуткого сокращения кода. P.S. для общего развития - чем плох switch на 10 вариантов? |
Автор: DeadSoul 11.4.2006, 21:29 |
Смотря в какой ситуации он используется. ![]() |
Автор: Earnest 13.4.2006, 12:04 | ||
А что не понятно? Форма записи - так сказано - такие же аргуметны, как у new, только вместо первого size_t (у new) должен быть void* (удаляемый указатель). Внутри (в твоем случае) может ничего не делать. А просто для "убрать предупреждение" достаточно #pragma - т.к. (в твоем случае) никакой утечки памяти произойти не может... Добавлено @ 12:09 В первую очередь, плохо-читабельность и плохо-сопровождаемость. Даже если на каждый case будет просто вызов функции, этот switch уже плохо-обозрим. И почему бы его сразу не заменить на явную таблицу функций? |
Автор: takedo 13.4.2006, 12:39 | ||
Вот и я не смог удеражться ![]() Ignat, - тебе просто не повезло, а что касается 14тыс строк - а так ли это много? Это всего лишь 280 страниц в стреднем. И обижаться на программиста нет смысла, так как сейчас действительно программистов используют "в темную", ставя не реальные сроки и не раскрывая того, что требуется. Вообще-то говоря путь есть, он прописан все в тех же ГОСТах, а именно, надо сформировать пакет следующих документов(примерный пакет): 1) технические требования 2) провести дополнительные исследования по результатам которых сформировать техническое задание 3) по техническому заданию сформировать план - график работ И проблем не будет! Но! Попробуй объясни заказчику, что именно так и только так он будет знать конкретные сроки(хотя они сразу же и возрастут, так как по тех заданию можно составить реалистичный, а не оптимистичный план). А тот программист в чём то прав. Сейчас его нет и без него программа не получает дальнейшего правильного развития. Я так понимаю, что на его коде основана база проекта, а вот на эту базу ты делаешь "довески". и деньги сейчас получаешь именно ты ![]() ![]() Я думаю, что вообще в наше время просто необходимо иметь программу, которая не только вычищат комментарии, но и переименовывает функции, например CreateBiilGates(int sex, int nationalnost) в Rl92384jk12324(int uioew89342kj,int sdf83sdf2087). Кстати, кто нибудь делал такую? ![]() |
Автор: Ignat 13.4.2006, 13:57 |
Погугли на предмет обфускаторов. Много можно найти. |
Автор: Earnest 13.4.2006, 15:30 | ||
Вообще-то это прямой саботаж и обман работодателя. Сданная работа - это не только exe (возможно с документацией), но и приличный код. Уж во всяком случае без преднамеренной порчи. И не надо оправдывать эту пакость тем, что тебе мало платят - ищи, в конце концов, другую работу. Любая халтура - она тебя прежде всего портит. |
Автор: UnrealMan 13.4.2006, 19:54 | ||||||||
Уже давно пробовал – предупреждение не исчезает.
Да я в курсе, но, по-моему, такое «убирание» предупреждений не есть хороший стиль программирования.
Чем же это плохочитабельно? И какова предлагаемая альтернатива? |
Автор: DeadSoul 13.4.2006, 22:41 | ||||||||
За такое ты рискуешь получить "очень хорошие" рекомендации. Только солибной фирме ты так не сможешь нагадить. SVN\MS SS умеют выдергивать старые версии. Добавлено @ 22:45
Виртуальные функции. Пример(пишу прямо тут, поэтому не обессудьте):
Добавлено @ 22:48 Далее, потребовалось добавить новый метод Draw. Код становится таким
Добавлено @ 22:51 Видишь switch-и плодятся! А теперь добавь еще один тип фигуры - треугольник. Во скольких местах тебе необходимо править код? Уже в двух, причем в реальном коде эти два(а ты уверен, что два? Ты все switch-и нашел? ![]() |
Автор: Earnest 14.4.2006, 08:15 | ||
Насчет альтернативы и сопровождаемости DeadSoul уже написал. А плохо-читаемость из-за плохо-обозримости. "Хорошая" функция должна занимать не более пол-страницы, чтобы с одного взгляда можно было понять, что она делает. И делать она должна что-то одно. Мне же приходилось видеть функции со switch'ами страниц на 20. Вот счастье-то, когда что-то поправить нужно. Сразу чувствуешь себя ассенизатором: надеваешь прищепку на нос, рукавицы по локоть и ныряешь в это. ![]() |
Автор: takedo 20.4.2006, 14:10 | ||||||
Оно все верно, когда вы изначально обговорили вопросы об авторсте. Плюс если вы сразу же знали, что от вас требовалось, а когда работа выполняется без четкого задания и вы за нее принимались, точно будучи уверенными, что пишете самокат, а в итоге от вас потребовалось написать аэрокосмичесую станцию, то... Вообщем, не очень хочется отдавать исходники, вот после того как зарегистрировать права, - можно, но и то только если очень попросят или об этом сразу была договоренность ![]() Добавлено @ 14:14
![]() |
Автор: DeadSoul 20.4.2006, 22:35 | ||
Как ты думаешь насколько сложно получить контракт человеку, пишущему прекрасный код, но имеющему отвратные рекомендации?! |
Автор: takedo 24.4.2006, 07:13 |
DeadSoul, да думаю, что даже полегче будет, чем тому, кто имеет великолепные рекомендации, но продукты которого периодически глючат. |
Автор: Earnest 24.4.2006, 08:15 | ||
Ты очень здорово ошибаешься. Работодателю более важна надежность и порядочность сотрудника (другими словами - лояльность), чем его программисские таланты. Конечно, полный лох никому не нужен. Но и самый разотличный программист, если он может выкинуть какой-нибудь фортель в описываемом духе - тоже. |
Автор: Ignat 24.4.2006, 09:57 |
Ну если он опытный программист, то еще лучше =))) А по теме: найти хорошее место работы при хороших проф. качествах и кол-ве смены рабочих мест, превышающих 7 в течение пяти лет, представляется сомнительным. |
Автор: DeadSoul 24.4.2006, 10:02 | ||
Таких людей называют "Летуны" |
Автор: takedo 24.4.2006, 10:59 | ||
![]() ![]() |
Автор: Xenon 28.5.2006, 13:50 |
Может и глупый вопрос, но я тут заметил, что, в основном, люди здесь, вместо того, чтобы преодпределить область имен using namespace std, просто постоянно делают разрешение видимости, типа std::cout и т.д. Это такой стиль (у Страуструпа в книге такой), или же в этом есть какой-то определенный смысл? |
Автор: DeadSoul 28.5.2006, 14:34 | ||
Смысл - не вносить идентификаторы из пространства имен std в глобальное пространство имен |
Автор: Earnest 29.5.2006, 11:06 |
Дополню: "using namespace x" может привести к кофликту имен: допустим в твоем контексте есть имя Y. Неважно, откуда оно взялось: это может быть локальный символ или нечто из другого пространства имен (введенное директивой using). Если в пространстве имен x тоже определено имя Y, то каждый раз при использовании Y в нашем контексте будем получать стоны компилятора о неоднозначности. Поэтому общий принцип такой: в заголовочных файлах вообще стараемся избегать директив using (даже using "конкретный символ", using namespace же запрещаем под страхом смерти). Чем шире используется заголовочных файл, тем сильнее избегаем. Внутри cpp-файлов и тем более внутри функций - вполне допустимо, можно поступать так как в данном контексте удобно. |
Автор: Alca 22.10.2006, 13:26 |
Кто-то грозился книгу выслать... [email protected]. Сп. |
Автор: Ignat 23.10.2006, 09:58 | ||
Ткните пальцем в тот пост. В противном случае, ваше сообщение - оффтоп. |
Автор: v2v 14.11.2006, 20:31 |
http://forum.vingrad.ru/topic-87958/0.html# - фот: Дата 21.3.2006, 13:19. UnixBeginner Я бы тоже хотел эту книгу: "formail1 @ gala.net" (без пробелов) |
Автор: Аленка 14.11.2006, 23:38 | ||||
Нас в институте учат сокращать код с if, else например, вот так-
до
Интересно, речь случайно не об этой http://www.books.ru/shop/books/314291? |
Автор: v2v 22.11.2006, 16:29 | ||
Возможно и об этой... интересно было бы почитать что-либо о стандартах программирования.. в частности на с++. |
Автор: bsa 22.11.2006, 16:36 | ||||||
Я б убил за это... Читать потом невозможно, а стандарты форматирования существуют не для компилятора, а для человека. Пиши лучше так:
|
Автор: Xenon 22.11.2006, 17:44 |
bsa, а я за перенос скобок бы убил ![]() |
Автор: bsa 23.11.2006, 13:52 | ||
Ты имеешь в виду перенос открывающей скобки на строчку оператора? Дело вкуса ![]() |
Автор: Xenon 29.11.2006, 19:45 |
bsa, да, но я этого жутко не люблю - потому что нельзя пробежаться глазами вертикально вниз от одной скобки к другой, чтобы найти конец и начало блока быстро. Приходится читать код ![]() |
Автор: nickless 29.11.2006, 23:40 | ||
Не надо писать вот так (перл новичка в С++, раньше писавшего на яве):
|
Автор: Uch3nik 30.11.2006, 20:03 | ||
Подскажите пожалуйста! Как получить доступ к данным в строках "ComboBox". Цикл такой:
Заранее спасибо. |
Автор: Poltergeyst 2.12.2006, 05:45 |
Привет всем умным и знающим я тут с таким вапросам как мне научится рязыку С++ ? дайте какие нибуть прожки несерьёзные плиз |
Автор: champion 2.12.2006, 07:27 |
Начни с указателей, они пригодятся тебе: http://forum.vingrad.ru/topic-60932.html А так советую, купи книжку Страуструпа, третье издание, специальное. Хорошая книга. |
Автор: GrayCardinal 2.12.2006, 08:17 | ||
Народ, да вы чего ? K&R рулит ![]() Кто-нибудь пытался прочитать код Vim ?! Не знаю, лично для меня даже libaal и kernel/sched.c проще читать. Там это, когда переносят скобку на следующую строку - не видно к какому оператору скобка да плюс читаете _две_ строчки вместо одной. А блоки (в нормальном коде) тупо по отступам видно. Насчет глобальных переменных. Ну и чего плохого в том, что будет глобальная структура со всеми настройками проги ? Лучше разбить на десяток объектов со своими свойствами, каждый из которых отвечает за свою функциональность ? А потом х.з. где у тебя "глубина дерева"................. Нет, _я_ конечно, найду... Тем же "бобиком", но................. Зачем ВЕЗДЕ И ВСЯ пихать классы ?! Хорошо научили что-ли, надо пользовать ? Насчет классов. Лично меня убивает когда прогу начинают с класса... В смысле CSpace (типа - космос), а потом вниз до функции "найти символ". (где моя "муха" ?! ) <Ы> Встречал разное... В том же Vim (наболело ![]() А я бы убивал тех, кто пишет на Haskell или "D", чесслово ! Вот тока винтовку достану ![]() |
Автор: Poltergeyst 2.12.2006, 08:35 |
Cасибо вы мне немногопомогли Ищу хорошего програмиста |
Автор: Daevaorn 2.12.2006, 12:26 |
GrayCardinal, у всех свой взгляд на проблему и свои привычки. |
Автор: V.A.KeRneL 10.12.2006, 05:06 | ||
От зависти что ли? ![]() |
Автор: zabivator 11.12.2006, 01:49 |
V_A_KeRneL, я подозреваю, что после этих языков народ пишет на плюсах через одно место. Хаскель я очень уважаю, если что =) |
Автор: V.A.KeRneL 11.12.2006, 04:36 | ||
Согласен, такие языки как Haskell хороши в качестве последних! После них уже не охота разбираться ни то что с какими-нибудь указателями, а вообще с тем, что должна ДЕЛАТЬ программа (механически). Главное понять задачу, а потом просто перевести задание на язык Хашкеля. Всё! Как прога будет добиваться нужного результата -- её дело; не маленькая; программисту над этим париться не хоцца!..)) Насчёт D ничиго не знаю, посему ничиго и не скажу. ОК! =) З.Ы. Haskell я буду изучать примерно через год, после C++. ![]() З.З.Ы. Но уже руки чешутся!.. И нет-нет, да и залезут в книжечку.)) |
Автор: Xenon 28.12.2006, 18:57 |
А если я, допустим, из своего класса вызываю некую внешнюю функцию (strcpy() например), я должен разрешать видимость и указывать на то, что функция из внешнего пространства имен вызывается (::strcpy())?Компилируется-то в любом случае - и когда класс помещен в какое-то стороннее пространство имен и когда нет ... |
Автор: bsa 30.12.2006, 15:58 |
Думаю, лучше указывать. Легче будет понять, что ты имел в виду. |
Автор: FelikZ 4.3.2007, 00:39 | ||
Как вам такое:
Неужели тяжело написать просто 'int', нет нужно писать такую чушь(очень часто в опен сурсах вижу). Вот за это Я бы убил! ![]() |
Автор: Daevaorn 4.3.2007, 00:51 | ||
раз это пишут, значит это нужно. Сегодня я использую int, а завтра захочу float, и что всё переписывать? Нет, я заменю всего один(!) дефайн или тайпдеф. |
Автор: FelikZ 4.3.2007, 14:47 | ||
Возможно ты и прав, но о какой красоте кода здесь можно говорить? Если на это посмотрит человек, не знающий о проекте ничего, но который хочет разобраться в нем? Он просто офигеет лазить по файлам(если проект огромный) и искать какой из дефайнов что означает... |
Автор: Daevaorn 4.3.2007, 14:52 | ||
за красоту не платят если хочет, то разберется и так
надо просто нормальные имена давать в таких случаях, чтобы из-за них и контекста было понятно что это. |
Автор: FelikZ 4.3.2007, 15:20 |
не факт, на некоторых работах за это платят.(напр. экстремальное програмирование) |
Автор: Daevaorn 4.3.2007, 15:40 | ||
спорно, но ладно, переформулирую: платят гораздо меньше чем за скорость разработки и качество |
Автор: FelikZ 4.3.2007, 16:23 | ||
Тут без сомнений ![]() |
Автор: popovda 23.5.2007, 16:36 |
Это все еще х-ня, господа. Вот я в НИИАП (нынче ФГУП Научно-производственный центр автоматики и приборостроения им. Н.А. Пилюгина), в 01 отделении работал, так там как есть из 77-го Фортрана на C++ Builder переписали. Как есть. С метками, с вычисляемым go to. Причем сами писали эмулятор этого вычисляемого go to. И switch на 30-40 единиц, и другие приколы. Я повеситься захотел, но потом просто сбежал. Ведь требуют - ты пиши так же. А я привык стандарту следовать.... И вообще непонятно, не проще ли было взять какой-нибудь Fortran Power Station 4 и на нем компилить. Или на современном Фортране написать. Бред... Теперь понятно почему у нас ракеты плохо летают. Американцам даже ПРО ненужно. Достаточно всего лишь еще какой-нибудь язык раскрутить, чтобы он тоже модным стал и загнать его нашим идиотам-чиновникам от науки и промышленности. P.S. Switch был не для отправки меssage, в нем до 500 строк в каждом (!) блоке.... Из них 300 дублируются. |
Автор: JackYF 25.5.2007, 21:04 | ||
Хы, это точно. P.S. Да что это у меня оффтоп пошел... |
Автор: qweasd 12.9.2007, 12:19 |
Сорри |
Автор: EugenOS 21.11.2007, 23:12 | ||
В 99.9999% случаев я с тобой полностью согласен, даже больше чем просто согласен. Но, недавно разбирался с одним девайсом, и там функция на подобие MD5, занимала половину ПЗУ контроллера, а вся работа девайса крутилась вокруг нее. Чтобы все это понять, переписал функцию на C++Builder, запускаю - результат не совпадает. Искал, искал нашел несколько возможных ошибок, повторюсь именно возможных. результат не совпадает. Эмуляторов на мотороловские контроллеры нормальных нет (потом откопал ZAS05) потому что они аппаратные производят. переписал функцию уже заменяя все на асм. результат изменился, но не совпадает. И все вроде правильно(переводил уже построчно) не тот результат хоть ты тресни. Потом откопал таки этот эмулятор(заставить его работать со своим бинарным файлом, это еще та проблема, к слову) и нашел в чем причина. На мотороле операции присвоения, сравнения, декремента и т.п. трогали гораздо меньше флагов чем в x86, понавставлял в циклах push/pop-ов и все заработало. Вот теперь и имею, нормально написанную программу( с кучей функций и интерфейсом и т.п.) и один файл в котором голимый асм а в комментариях асм 68HC05. И честно признаюсь - рефакторить это я не буду, ни за какие коврижки. Как говорилось в анекдодоте: - Папа, а почему каждое утро солнце встает на востоке, а вечером садится на западе? - Ты уверен? - Да - Точно работает? Без сбоев? - Да... - Слушай сынок, никогда, ни за что не трогай, не дай бог сломается, потом работать не заставишь. |
Автор: nickless 21.11.2007, 23:48 | ||
Как говорится орфография и пунктуация аффтара сохранены ![]() |
Автор: Helcar 1.12.2007, 05:33 |
Если код оформлен читаемо то и рабираться в нём легче. По поводу swtch`ей - в некоторых случаях без них не обойтись (пример программа под чистый WinAPI), так что, если оно работает то и плохо оформлено, то оформление можно немного поправить. Главное что бы поле надстройки оно так же хорошо работало как и без нее. Кроме того лично видел несколько реализаций в которых использовалось goto, да там можно без этого обойтись, просто по моему стоит помнить и о оптимизации кода, по быстро действию втом числе. Не нужно накручивать лишнего если без этого можно обойтись. А вообще можно к описанному в первом посте кассу добавит несолько функций открывающих доступ к нужым фн-ям в нутри него, после чего написать свой класс, а исходный использовать как челен своего класса. И никаких проблем. |
Автор: CppDevelopeR 28.3.2008, 13:12 | ||||||||
Пару лет назад, еще начинал программировать написал так:
переделал на(ваще обаржаца ![]()
Хотя мой препод сказал, что второй код работает на некоторых компиляторах. Долго не мог сообразить. Мы все конечно знаем что писать можна так:
или:
З.Ы. Переменная i использовалась просто так, для наглядности! |
Автор: deninok 28.3.2008, 13:16 | ||||
Вообще, не рекомендуется использовать в одной строке более одного действия (за редчайшими исключениями). То есть код
лучше переписать так:
|
Автор: CppDevelopeR 28.3.2008, 18:23 |
Согласен! ))) Но всетаки у всех есть вредные привычки. Давно бы надо от нее отделаться. ![]() |
Автор: 0lmer 9.4.2008, 16:36 |
Недвно видел такое ![]() //считаем согласные буквы. #include <stdio.h> #include <string.h> void main() { int i=0; //количество символов. int s=0;// колличество согласных букв. char C=0; printf("vedite predlojenie:\n"); scanf("%s", strlen); for(int i=0;i!=0; i=i++); printf("kolichestvo simvolov v stroke %d",i); if (C='Ц','К','Н','Г','Ш','Щ','З','Х','Ф','В','П','Р','Л','Д','Ж','Ч','С','М','Т','Б'); printf("kolichestvo soglasnyh bukv %s",s); system("PAUSE"); return; } |
Автор: kosmonaFFFt 16.4.2008, 11:38 | ||
Недавно видел такое:
Долго ржал когда мне скинули СКРИНШОТ этого кода в билдере и попросили посмотреть где ошибка. |
Автор: Rocksteady 19.4.2008, 23:43 | ||
У нас чувак на работе запросто пишет такой код:
Типа сначала "изнасиловали" объект явным приведением, а потом еще "вот тебе, маленький, аккуратный динамик_каст" ("хотя он тебе уже мало чем поможет")... |
Автор: Earnest 21.4.2008, 15:35 |
Да нормально сработает: если компилятор приведение видит, нормально сработает уже c-приведение, а dynamic cast - просто лишний. Если же компилятор не знает как привести (первое), то адрес не изменится, а тут как раз dynamic_cast подскочит. Хотя код конечно дурной: устройте ему темную, что ли, если начальству все равно. |
Автор: UnrealMan 23.4.2008, 00:47 | ||
Не факт. Совсем не факт.
![]() Вот рассуждениями примерно такого уровня руководствуются авторы подобного кода. |
Автор: Earnest 23.4.2008, 08:20 | ||
Это нужно обосновать.
Правильная работа - не единственный критерий хорошего кода, и даже не самый главный. |
Автор: UnrealMan 23.4.2008, 13:10 | ||||
Обосновать как раз нужно было обратное. Стандарт не даёт никаких гарантий правильности работы этого кода применительно к общему случаю. Но если стандарты для вас не писаны, то тогда просьба показать компилятор, который скомпилирует вот это
и который здесь
в обоих случаях сделает вывод числа 123. |
Автор: Earnest 23.4.2008, 16:47 |
Ну уел, уел, с виртуальным наследованием все сложнее, только чего так напрягаться-то, мог бы и поспокойнее написать. ![]() |
Автор: mastaflow 3.5.2008, 17:58 | ||||
сегодня пронаблюдал такой код (под бс3.1)
далее очень интересная функция:
Особенно мне понравилась идея &(*flag) |
Автор: kosmonaFFFt 3.5.2008, 18:18 | ||
Тоже один раз подобное видел. ![]() Или вот еще недавно наблюдал код примерно такого содержания:
|
Автор: Lycifer 7.7.2008, 13:16 | ||
kosmonaFFFt - вопрос такой:
Как это скампилируеются ![]() ![]() |
Автор: kosmonaFFFt 7.7.2008, 16:45 | ||
как это компиллировалось не видел ![]() был приложен экзешник, который умел только дико глючить. |
Автор: Ulysses4j 7.7.2008, 18:22 | ||
Кстати, вполне нормаьлный мог бы быть код, если бы flag был итератором. |
Автор: Torsten 13.7.2008, 12:01 | ||||||||||||||||
Аленка,
Тернарный оператор должен иметь только одно условие, иначе он плохо читается. В данном случае одна из лучших записей такого кода, будет выглдядеть вот так :
GrayCardinal,
Глобальный переменные использовать в С++ нельзя, это признак непрофиссиональность. Хранить настройки проги нужно в классе сингтоне. Классы везде пихать не нужно. Если функция не имеет отношения к классу ее нужно вынести отдельно с собственным пространством имен (namespace). FelikZ,
В дефайнах - неправильно. В typedef - правильно. Подробнее об этом в книгах написано.
Для этого и нужны IDE, там достаточно нажать один раз хоткей чтобы перенестись к месту обьявляния. Ну а самые продвинутые, так вообще специальных textEdit могут показывать это (в VS вверху он находится по умолчанию над редактором), нужно лишь курсор на тип поместить чтобы увидеть как он определен. |
Автор: Kallikanzarid 12.11.2008, 10:07 | ||
Лучше тогда уж error<id>::message, если конечно нет необходимости регистрировать ошибки в рантайме. |
Автор: Kallikanzarid 12.11.2008, 10:46 | ||||
Вот он удивится при портировании на x64 ![]() |
Автор: bsa 12.11.2008, 13:55 | ||
Ты выравнивание имел в виду? |
Автор: Kallikanzarid 13.11.2008, 03:14 | ||||||
Сейчас проверил - видимо, я плохо знаю стандарт.
Работает ![]() |
Автор: nickless 14.11.2008, 18:43 | ||
Оно конечно работает (во всяком случае под 32 бит и gcc), но это не стандарт
|
Автор: Kallikanzarid 14.11.2008, 19:54 |
Это не противоречит коду выше. Скорее всего, компилятор просто учел выравнивание и преобразовал (&x)[index] к ((char*)&x) + 8*index). Хотя, конечно, не факт, что будет компилироваться везде. |
Автор: Fire-Plug 19.1.2009, 08:32 | ||||||
Полагаю, что вы не совсем поняли, что он предложил, а именно - вызвать конструктор класса через его полностью квалифицированное имя (fully qualified name), т.е.
хотя ПМСМ - это мазохизм в тяжелой форме. В тех упражнениях, что он предлагает, этот подход ещё можно как-то использовать и воспринимать как курьёз. В реальных ООП проектах - это просто бред голимый. Например, как он собиратеся вызывать деструктор по указателю на базовый полиморфный класс, т.е. виртуальную ф-цию? Каким макро он собиратеся это делать? ООП - это не только класс/структура с конструктором/деструктором и new/delete vs calloc/malloc/free. Это - как раз именно наследование и полиморфизм. Так что подход, предлагаемый UnrealMan, можно выразить слоганом: прощай ООП. Советую не принимать близко к сердцу, т.к. ник товарища говорит о многом - ну не любит он общепринятых решений для стандартных ситуаций. НО есть положительный момент - заставляет снова осмыслить рациональное зерно С++ и его принципиальные отличия от С - и не только в плане выделения памяти. В конце концов, имеется placement new оператор... |
Автор: Fire-Plug 19.1.2009, 09:39 | ||
Э-э-э-х, ваше счастье, уважаемый, - не видели вы гигантских С-шных проектов с файлами по 20+ тыс. строк кода и проектами к-либо из бизнес-компонент системы по 5,5 тыс. функций. Просто ф-ций; не методов; с тысячами callback-ф-ций - этим С-шным способом реализации полиморфного поведения... Лучше бы мои глаза их тоже не видели... Когда-то мне очень нравился этот язык, а теперь - ненавижу. Может даже не сам язык, а тех козлов - нынешних ветеранов-старперов и теперь уже почти сплошь директоров и менеджеров, кто за 15+ лет так не попытался мигрировать проект в ООП на С++, когда это еще было возможно. Теперь по неофициальной оценке code base превышает 6 млн. строк и нет ни возможности, ни ресурсов, ни самое главное - желания осуществить миграцию. Контора, плять, стабильная - неплохо платит и от дома 6,5 км... Пол-года маюсь и никак не решусь начать искать другую работу, чтобы о С не слышать больше вообще. Ладно, эмоции в сторону. Объявление С-ф-ции(и/или переменной) в c/cpp-файле как static ограничивает ее область видимости рамками данного файла. Т.е. ниоткуда больше, как из данного файла, ф-ция не видна и, следовательно, не может быть вызвана, а переменная - не имеет доступа извне. При этом декларация ф-ции также находится в том же файле, а не в к-либо файле заголовка. Идея - этакий вариант С-шной инкапсуляции. Наверное, в 1970 г. это была "плодотворная дебютная идея" (с). Как видите - нет ничего общего со статическим методом/переменной-членом класса, кроме как самого модификатора static ![]() |
Автор: zim22 25.1.2009, 17:59 | ||||
В книге С++ Primer рекомендуют избегать глубокого вложения условных выражений. И приводят 2 примера кода для нахождения максимума из 3 значений. 1) Этот код не рекомендуют:
2) Пишут, что это значительно проще и наглядней:
Вы тоже согласны с авторами? Лично мне кажется, что первый вариант наглядней... |
Автор: mes 25.1.2009, 18:08 | ||
так как раз у второго кода вложение гораздо глубже ))) а третьего варианта там в пример не привели ?
|
Автор: zim22 25.1.2009, 18:17 | ||||||||
о, отличный код! не привели, т.к. до stl не дошли ещё. до введения понятия итератор вектор проходили с помощью такого цикла:
после введения итератора примеры в книге поменялись:
Так что возможно когда до STL дойду, они исправятся и извинятся за некрасивый код ![]() |
Автор: bsa 29.1.2009, 18:36 | ||||||
Отлично. Вот только std::vector - это уже STL. |
Автор: ДокторТуамОсес 10.6.2009, 16:17 |
А каким способом можно обойтись без свитча на большое кол-во вариантов? |
Автор: just_geek 15.6.2009, 04:11 |
можно хэш ) в качестве значения указатель на функцию... но громоздко выйдет ![]() |
Автор: ДокторТуамОсес 15.6.2009, 10:00 |
Вот и я про то же. Чел ругает свитч со многими варианами, а своего, более краисвого и элегантного, решения не предлагает. И видимо его просто нет. ИМХО, не вижу ничего не красивого в свитче со многими вариантами. Всё очень читабельно и понятно |
Автор: mes 19.6.2009, 19:51 | ||||
Чтоб предложить решение, нужно знать задачу. Для искоренения свитча есть несколько вариантов, хотя в принципе все они основаны на таблице функций.
Ну да.. если вся программа состоит из единственного свитча. ![]() |
Автор: ДокторТуамОсес 19.6.2009, 23:32 | ||
Ругаете свитч на 10 вариантов? Говорите что это "ужас", "кошмар"? А как Вам это (то что я привёл ниже)? Это очень читабельно? Это не "ужас"? Тем не менее это реальный код из микрософтовского инклуда c:\Program Files\Microsoft Visual Studio\VC98\Include\COMDEF.H студии MSVC++ 6.0 Всем понятно что делает этот код?
|
Автор: azesmcar 19.6.2009, 23:34 | ||
А кто говорил что его читать надо? ![]() Вы еще бинарник попробуйте прочитать. |
Автор: ДокторТуамОсес 19.6.2009, 23:38 |
Тема называется "как не надо писать код" Но ведь код из моего примера был написан кем-то. Да не кем-то, а самой главной программистской фирмой - "Microsoft" |
Автор: azesmcar 19.6.2009, 23:41 | ||
Это сложно назвать кодом. Это обыкновенный def файл, по другому он и не мог выглядеть, тут нет логики и нет выполнения инструкций..обыкновенные обявления.
Хотите поглядеть на плохой код микрософта - загляните в MFC. |
Автор: nix_crash 20.6.2009, 23:25 |
![]() |
Автор: ДокторТуамОсес 21.6.2009, 23:00 |
«Предыдущий оратор, который убеждал нас пользоваться библиотекой Microsoft Foundation Class (MFC), сказал нам, что поддержка OLE в MFC "включает 20000 строк кода, необходимых для каждого /* ![]() |
Автор: GoldFinch 21.6.2009, 23:25 | ||||||
вместо switch
Добавлено через 9 минут и 50 секунд
у меня есть файл Excel где забиты формулы вида =ПОДСТАВИТЬ($B$1;"$";A3) =ПОДСТАВИТЬ($B$1;"$";A4) ... что позволяет сгенерить любое число однотипных строчек по списку подстановки да, Excel пишет плохой код... |
Автор: azesmcar 22.6.2009, 10:28 | ||
Какой еще оратор? Или это цитата? Тогда откуда? |
Автор: jonie 22.6.2009, 10:37 | ||||
а что там непонятного? определяет умные указатели, притом это "стандартно" и "общепринято". В чем проблемы-то? ЗЫ: по теме: есть сайт http://govnokod.ru/ (не сочтите за рекламу) - смотрите его) |
Автор: ДокторТуамОсес 22.6.2009, 22:42 |
Вот отсюда В сообщение же было указано откуда цитата. А где находится список литературы - указано в моей подписи |
Автор: azesmcar 23.6.2009, 08:36 | ||
замечательно...7-ая страница. Или 6-ая? Интересно 7-ая странице "чего?" На 7-ой странице данного топика (да и на 6-ой тоже) я такого оратора не нашел.
А из нашего окна площадь Красная видна. зачем мне список литературы? ![]() Хотя я понимаю ваше бурное и непреодолимое желание повысить посещаемость своего ресурса. |
Автор: kosmonaFFFt 23.6.2009, 09:31 |
список литературы тут при том, что цитата из книги, не помнб правда названия... |
Автор: azesmcar 23.6.2009, 09:36 | ||
Ах да, наверное я их должен был всех перечитать и наизусть запомнить. |
Автор: ДокторТуамОсес 23.6.2009, 17:53 | ||||
Дык я не понял. Вы посмотрели список литературы или нет? Добавлено через 2 минуты и 3 секунды
А вот я смысл Вашего "выпада" не понимаю. Вас что не устраивает-то? То что когда я кого-то цитирую, то привожу данные того, кого я цитирую? |
Автор: azesmcar 23.6.2009, 18:50 | ||
Смысл моих "слов" в том, что если вы кого-то цитируете - сообщите кого, а не указывайте страницу в книге, которая описана на другом сайте. Возможно у меня нет ни малейшего желания посещать другой ресурс и там копатся в ссылках. Пишите что-то здесь? - так пишите до конца, уже не в первый раз замечаю за вами сообщения типа: посмотрите мой вопрос тут. А это наводит на мысль, которую я кстати и высказал. |
Автор: jonie 23.6.2009, 20:32 |
кстати еще одно "но" отсюда : не нужно в коде писать комменты вроде "чтобы понять что это, посмотрите в функции foo класса bar в строке 24"....) |
Автор: zim22 24.6.2009, 18:41 | ||
![]()
зря вы все гоните на ДокторТуамОсес'а. он уже "пол-книжки" Подбельского откритиковал ![]() http://doctortuamoses.0pk.ru/viewtopic.php?id=117 (красненьким шрифтом - его уточнения) |
Автор: Alca 24.6.2009, 19:14 | ||
![]() |
Автор: azesmcar 24.6.2009, 19:24 | ||
Да ради бога, пусть хоть Саттера критикует, только не надо в разговоре расчитывать на то, что я все это читал (или буду читать) ![]() |
Автор: zim22 25.6.2009, 08:45 |
вы пол жизни потеряли. его критика - это нечто! советую посмотреть ![]() *** ДокторТуамОсес, в плане посещаемости сайт у вас ни ахти. я вчера в 9 утра http://doctortuamoses.0pk.ru/viewtopic.php?id=170 запостил. прошло 24 часа. никто в неё даже не зашёл... сколько мне с ответом ждать? ![]() |
Автор: azesmcar 25.6.2009, 08:48 | ||
иду смотреть ![]() |
Автор: JackYF 25.6.2009, 18:36 | ||
ДокторТуамОсес, спасибо, посмеялся. В частности, http://doctortuamoses.0pk.ru/uploads/0004/6c/9e/390-1-f.jpg, замечание про "\r" и "\n" в корне неверно.
А ссылки выше в этой теме будут оставлены для того, чтобы у других участников не возникало вопросов "почему?". |
Автор: zim22 25.6.2009, 21:50 | ||
![]()
шепчу на ухо: у него в подписи ссылки на форум остались ![]() |
Автор: ДокторТуамОсес 26.6.2009, 14:39 |
Ничего. Через годик-два раскрутиться. Все когда-то начинали с малого. Говорят, что "обещанного 3 года ждут"© ![]() P.S. Ответил ![]() |
Автор: MasterOfMuppets 29.3.2010, 09:16 | ||
Одногруппник отжог. Прислал код лабы по ОС... долго ржал. Даже не удосужился поставить какой-нибудь линукс на виртуальную машину, чтобы его откомпилить - результат: (как есть, ничего не менял)
Начнём с дифайна - ну не научили чувака, что эта хрень нужна только для визуал студии)) Как на первой лекции по С научили 2 года назад, так и юзает везде как ритуал ![]() далее, смесь транслита и ломаного английского сразила просто наповал! Так же осталось загадкой, зачем открывался файл... Задание было - создать новый процесс, и в нём запустить /bin/ls с параметрами, передаваемыми в командной строке, и предусмотреть простенький хелп... Ну неужели так трудно... |
Автор: Earnest 30.7.2010, 07:33 |
Внимание! Хвост темы с базаром про ООП\не ООП перенесен в религиозные войны. Ругайтесь там, если охота. А здесь прошу высказываться по теме, если есть что сказать. Все прочее будет удаляться без предупреждения. |
Автор: Randajad 18.3.2012, 12:17 | ||
Очень интересное мнение участников про malloc.
А что участники думают по поводу этого? std::vector для классов, которые внутри себя выделяют память не подходит, потому что вектор все время переконструирует и вызывает оператор=(), когда закончилось место в буффере/удаляют элемент из середины массива; это все дико тормозит. Кстати. Еще в правила: не нужно использовать NULL. Это макрос и он задефайнен где-то там. Лучше 0. Или, с выходом С++0х можно еще nullptr. |
Автор: Фантом 18.3.2012, 13:36 |
Код на C++, в котором в первой же строке константа определяется макросом... что тут еще можно думать? ![]() |
Автор: Randajad 18.3.2012, 18:13 |
И что же вы находите такого плохого в дефайнах препроцессора? ![]() |
Автор: bsa 19.3.2012, 13:18 |
А что тут думать? Вопрос находится в теме "как не надо писать код". Ответ очевиден. ![]() Самый быстрый доступ к элементам в векторе. Самое быстрое удаление/вставка в середину в списке. Если тебе не нужен случайный доступ, а достаточно последовательного, то лучше выбрать список. Если тебе необходим случайный доступ, а размер элементов не больше указателя, то быстрее вектора вряд ли что будет. Если ты используешь большие массивы больших элементов и случайный доступ необходим, то можно сделать нечто среднее, между списком и вектором. Т.е. в списке у тебя хранятся сами элементы, а в векторе хранятся указатели на них. Таким образом, при добавлении/удалении элементов, вектор будет работать только с простыми указателями (это быстро), а список с элементами. Пример такого контейнера - QList (Qt). |
Автор: Randajad 25.3.2012, 17:45 |
Это все хорошо, но необходим также доступ к элементам в стиле обычного массива. ![]() Так что увы, ничего подходящего не нашел, кроме как самописный вариант. |
Автор: bsa 26.3.2012, 17:51 | ||||
|
Автор: Randajad 27.3.2012, 08:40 |
Я имел ввиду чтобы: array<int> arr; Было равно int arr[]; И все элементы стояли друг за другом в одном куске памяти. ![]() |
Автор: baldina 27.3.2012, 10:26 |
если у объекта тривиальный конструктор/деструктор накладных немного. если нетривиальный, объект (или объекты с ним связанные) может быть обескуражен неожиданной сменой адреса. так что именно vector подходит "для классов, которые внутри себя выделяют память". память кстати по-разному выделять можно. скажем, копирование при записи. так что это скорее проблема класса-содержимого, а не контейнера. желание иметь элементы в памяти "одним куском", причем именно элементы, а не указатели законно, но не понятно. приведите пример, когда это действительно необходимо. мне в голову приходит только работа с низкоуровневыми библиотеками, но они в основном работают с элементарными типами данных, для которых перемещение в vector реализовано как раз через memmove. кстати. никто не мешает вам сделать свою специализацию класса vector. |
Автор: Randajad 14.4.2012, 17:42 |
Объекты внутри себя не хранят ссылок друг на друга, в этом вся фишка. Выделение через new памяти для каждого объекта не хорошая идея потому, что размер объекта маленький, а их число порядка десятков тысяч. Таким образом из-за выравнивания и данных менеджера памяти получится слишком большое количество памяти "впустую". |
Автор: baldina 14.4.2012, 21:44 | ||
|
Автор: heavix 15.5.2012, 11:31 | ||
10?)) Это еще ничего))) Вот сейчас у меня проект, в котором есть функция принимающая 43 параметра, причем одного типа mxArray... Корень всех бед проекта... И самое паршивое что я сделать ничего не могу, т.к эта функция дергается из длл-ки написанной в матлабе( А математику делаю не я... Вот и наступает вынос мозга когда человек делающий мат часть начинает требовать передачи параметров номер 3,9,12 как uint8, 14,16 как стринг... но все нуно конвертить в mxArray )) |
Автор: ТарасАтавин 29.8.2013, 18:44 | ||||
А почему так мало? Уж если автор идиот, то должна быть пара тысяч. Добавлено @ 18:51
Добавлено @ 18:59
|
Автор: ТарасАтавин 29.8.2013, 19:07 | ||
Самое веселое - это писать вообще без отсупов, а на плюсах так ещё и всё в одну строку. Добавлено через 1 минуту и 11 секунд Вот ещё пособие, как делать не надо:
Добавлено через 4 минуты и 1 секунду И поминавшийся здесь явный вызов конструктора. Конструктор и деструктор придуманы именно для того, чтоб вызываться автоматически, чтоб уж точно не забыть из вызвать и, наоборот, не забыть, что уже вызвал. |
Автор: ТарасАтавин 30.8.2013, 04:58 |
Рекурсия бывает оправдана при обработке рекурсивных данных, например, деревьев. Но рекурсия на пустом месте - это именно то, чего делать не надо. |
Автор: Jeka178RUS 2.9.2013, 13:00 |
Чем же рекурсия так плоха? Накладные расходы на вызов функции, как мне кажется, не существенны (не берем в расчет критические отрасли, как контроллеры и пр.). Разве что отладка не удобна |
Автор: bsa 2.9.2013, 15:01 | ||
рекурсию на пустом месте делают только преподаватели. Сам программист редко когда делает рекурсию там, где и без нее все хорошо получается. |
Автор: ТарасАтавин 3.9.2013, 05:45 | ||
Преподаватели этим занимаются при подаче нового материала по теме "рекурсия", чтоб показать, что это вообще такое. Но когда ею пестрят учебные поделухи, это нормально. В реальных же прогах рекурсия должна быть там и только там, где она вытекает или из задачи, или из представления данных. Да и то бывает, что вместо рекурсии надо обратиться к математику, который объяснит, что матрицу экономнее привести к треугольному виду, а потом перемножить главную диагональ, чем считать определитель рекурсивным алгоритмом. На КМК есть целый отдел любителей рекурсии. Добавлено @ 05:53
Добавлено @ 05:56 Явный вызов конструктора отлично заменяется присваиванием вспомогательного локального объекта, в котором напутать уже нельзя. А вот к чему приведёт двойной вызов конструктора для одного и того же динамического объёкта по указателю без тестов не разберёт и сам Страуструп. |
Автор: bsa 3.9.2013, 10:30 | ||||
и вообще. Языки С/С++ очень гибкие. Поэтому на них очень легко получается совершать ошибки. Хочешь не совершать? Пиши на Ada. |
Автор: Jeka178RUS 3.9.2013, 12:37 |
Замечательный пример "как не надо делать" я нашел в недрах Ericsson Labs: в одном файле https://labs.ericsson.com/blog/updated-ericsson-texture-compression-tool 16 000 строк кода на С. Насколько нужно быть упоротым человеком чтобы так кодить? |
Автор: ТарасАтавин 5.9.2013, 11:24 |
Затем, что забыл, что один раз уже вызвал. Добавлено @ 11:26 Думаешь я не реаллокил массивы объектов? Нормально он себя поведёт, непроиниченный объект просто содержит мусор. Ну и что, если его всё равно надо затереть нормальными данными? |
Автор: bsa 5.9.2013, 12:30 | ||
Кстати, а ты вообще знаешь, как вызвать конструктор класса? А деструктор? И часто ты их вызываешь вручную? Кстати, следуя этой логике не нужны и new/delete, так как можно два раза выделить память. |
Автор: ТарасАтавин 5.9.2013, 14:09 |
Сам читай. У меня 13 лет практического опыта. Добавлено @ 14:11 Ни когда. А как тогда вообще хоть что то писать? Резервировать массивы, как во времена лорда Клайва Синклера? К тому же new/delete мудрено забыть, так как они естественно вытекают из динамического создания/удаления. А конструкторы/деструкторы придуманы именно для того, чтоб вызываться неявно. Иначе юзай вместо них методы Create/Free, больше ни в чём конструкторам/деструкторам не уступающие. |
Автор: bsa 5.9.2013, 15:26 |
Опыт опыту рознь. Некоторые новички и то больше знают и умеют. Ответ на вопрос о способах вызова конструктора и деструктора я так и не получил. Значит не знаешь. Тогда о чем вообще речь? Как ты можешь критиковать что-то, что ты вообще никогда не видел и уж тем более не задумывался о назначении. Это к тебе вопрос, а не ко мне. Так как это ты выразил мысль, что явный вызов конструкторов и деструкторов не нужен, так как может привести к повторной инициализации. Так как кто-то книжки читать не любит (видимо на основании 13-ти летного опыта), то справочно сообщаю, что явно вызвать конструктор класса можно только используя так называемый http://ru.wikipedia.org/wiki/New_(C%2B%2B)#Placement_new (указанный пример кода показывает на сколько это нетривиальная операция, по которой даже нельзя сказать, что это вызов конструктора). А операция MyClass() не является вызовом конструктора в чистом виде - это фактически создание временного объекта связанное с вызовом указанного конструктора. |
Автор: ТарасАтавин 5.9.2013, 16:05 | ||||
Добавлено через 3 минуты и 58 секунд
|
Автор: akizelokro 5.9.2013, 16:11 |
Тарас, цепляй ObjectiveC. На Западе многие его юзают, кстати. По крайней мере в заказах постоянно вижу. |
Автор: ТарасАтавин 5.9.2013, 16:11 |
О присваивании непроиниченному объекту? Ну ну. Я это практически делал. И наблюдал под дебагером, что именно у меня получалось. Добавлено через 1 минуту и 28 секунд Си с классами вместо полноценного объектного языка? Сам цепляй эту полумеру. |
Автор: bsa 5.9.2013, 17:37 | ||||||||
Добавлено через 1 минуту и 5 секунд
Добавлено через 8 минут и 34 секунды Кстати, есть очень красивая реализация оператора присваивания с использованием создания временной переменной:
|
Автор: ТарасАтавин 7.9.2013, 08:03 | ||||||
Добавлено @ 08:08
1. Может вызываться не явно при входе в область видимости, в которой декларирован автоматический объект, при загрузке модуля, в котором декларирован статический объект и из оператора new. 2. Предназначена для начальной инициализации объекта, За назначением остальных функций следит автор, в том числе их можно предназначить для той же цели, что и конструктор. И что же остаётся от конструктора, если его пытаются вызвать явно? Placement new же вызывает конструкторы не явно. Кстати, пустые конструкторы инициализацией не занимаются, их назначение - соблюдение формального правила о создании объектов только через конструктор. Но почему-то
|
Автор: bsa 9.9.2013, 11:26 | ||||||||||||
Может написать отличия?
Она вызывается не при входе в область видимости, а при инициализации переменной (объекта). Т.е. если переменная объявлена в конце блока, то конструктор она не вызовется сразу при входе.
Ты можешь сколько угодно тут разводить демагогию про явно и неявно, но placement new делает только одну операцию: вызов конструктора класса для инициализации объекта в указанной области памяти. И все! Поэтому я никогда бы не сказал, что он делает это неявно.
|
Автор: ТарасАтавин 18.9.2013, 14:36 | ||
|
Автор: Guinness 18.9.2013, 14:42 |
ТарасАтавин, вообще-то, это классика как нужно писать оператор присваивания, чтобы делать его "безопасным для исключений"(тут с термином мог ошибиться, не помню как у Саттера там классификация идет). Более того, таким образом мы гарантируем, что и копирующий конструктор и оператор присваивания у нас делают одно и тоже. А если конструкция не привычна для восприятия, то нужно привыкать. |
Автор: ТарасАтавин 18.9.2013, 18:56 | ||
{ MyClass(other).swap(*this); }[/code], конечно. Кстати, оператор присваивания обязан возвращать ссылку на this, так что ваша "классика" страдает грубым нарушением стандарта. |
Автор: mes 18.9.2013, 19:49 | ||
правый операнд это other ? больше ничего с конст не нахожу.. и где ктор его меняет ![]() ![]() ![]() Добавлено через 2 минуты и 9 секунд
а как насчет того, чтоб читать между строк ? эта строчка с возвращением this никакой роли не влияет, потом в форумных примерах на коленке может быть безболезнено упущена ![]() Добавлено через 6 минут и 49 секунд ![]() ТарасАтавин, был тут на форуме уже докторКтоТоТам, тоже себя в грудь бил и кричал громче всех.. еще и книжки писал.. Вы еще не пробовали ? что ж ценный опыт пропадает ... |
Автор: baldina 19.9.2013, 10:42 |
немало ИТшных форумов, где он был заблокирован... ![]() |
Автор: bsa 20.9.2013, 12:34 |
ТарасАтавин, расскажи, что делает конструкция MyClass(*this)? |
Автор: azesmcar 24.9.2013, 13:46 | ||
вообще-то любая функция, которая при возникновении исключений гарантирует отсутствие утечки ресурсов уже сама по себе является exception safe, так-как соответствует базовому правилу безопасности исключений Абрахамса (раз уж вспомнили Сатера, то Сатер в своей книге цитировал именно его). А сохранение состояния программы при возникновении исключений является строгой гарантией, которую можно обеспечивать а можно и нет, зависит от программы. |
Автор: azesmcar 24.9.2013, 16:04 | ||||
Да, а что если это не тривиальный объект с двумя целочисленными типами а скажем что нибудь посложнее..ну например вот такой класс
Что буде на 21-ой строке, если он содержит мусор? |
Автор: ТарасАтавин 7.10.2013, 18:26 | ||||||||
swap. Добавлено @ 18:28 Даже если return *this спрятано внутри swap, реализация оператора присваивания не содержит этой операции, а по стандарту должна. Добавлено @ 18:31
Добавлено через 10 минут и 20 секунд Копирует, да вот беда: анализ подобных мелочей занимает лишнее время, а по закону Мёрфи, гласящему что всё, что может быть понято не правильно, именно так и будет понято, кто нибудь обязательно его вообще не заметит. |
Автор: ТарасАтавин 7.10.2013, 18:46 |
А как на счёт объекта, декларация членов-данных которого занимают более пяти экранов? malloc от этого не зависит, а первое же присваивание мусор затрёт. А объект, знающий, что он - узел дерева с динамическим массивом потомков и при этом ещё одновременно содержащий несколько динамических массивов объектов других классов, чьи экземпляры не знают, где они валяются? в указатель отдельным присваиванием пишется NULL, потом присваивание всего объекта, затирающее остальной мусор. Только это не удобно. А удобно и уместно вызывать конструктор оператором new. |
Автор: bsa 9.10.2013, 10:59 | ||||||||||
ТарасАтавин, ты что к мелочам цепляешься? Тебе концепцию показывают. Естественно, что в нормальном коде должен быть и return *this. Он в данном случае не он главное. Главное, каким образом реализуется основная функциональность.
Добавлено через 9 минут и 45 секунд
|
Автор: ТарасАтавин 9.10.2013, 12:34 | ||||||
Добавлено через 2 минуты и 36 секунд Какая разница? Речь о том, что код читается, как
|
Автор: baldina 9.10.2013, 12:38 | ||
не совсем, это слишком узко. правило в том, что у объекта должен быть хозяин (владелец), который управляет. выделение памяти может быть делегировано (фабрике например), делегировано может быть и освобождение (хотя это реже применяется). владение может передаваться, что и происходит с умными указателями. так что они не исключение, а подтверждение правила. Добавлено через 1 минуту это уже мозгоклюйство. ведь все всё поняли. |
Автор: bsa 10.10.2013, 12:02 | ||
![]() Где ты мусор тут нашел? Оператор присваивания ВСЕГДА оперирует с инициализированными объектами. Если какой-то негодяй не инициализирует объекты в конструкторе, то это его проблемы. Дальнейшие рассуждения по поводу качества кода с ним можно не продолжать. |
Автор: Lukkoye 4.1.2014, 01:27 | ||
Существует миф, который заслуживает того, что бы его разоблачили. Действительно: вставка у листа быстрая. Однако, реализация со стандартным аллокатором задействует оператор new. Который черезвычайно медленный. Настолько медленный, что за это время можно несколько раз вставить элемент размеров в 32 байта и в количествt 1000 штук (я делал замеры по скорости, но это было давно и точных цифр не помню) в вектор путем копирования его элементов в право (расширение), при условии, что у вектора достаточно резерва и он не реалокнется. Таким образом, если вы используете стандартный аллокатор листа, который идет в с ним по дефолту, то по скорости работы на прикладных задачах он редко когда выигрывает у вектора. И никогда не выигрывает, если количество элементов - не велико. Использовать его ради достижения перфоманса имеет смысл, если вы используете свои аллокаторы с уже заранее зарезервированной памятью. И не имеете потерь на её выделение оператором new |
Автор: baldina 4.1.2014, 22:08 |
Ну мифа-то нет никакого, речь идет об асимптотическом поведении, а константы могут быть сколь угодно большими. что касается замеров скорости, я не вижу подтверждения: http://ideone.com/bAzcuQ |
Автор: azesmcar 13.1.2014, 16:47 | ||
baldina Хитришь ![]() Сравнение не честное, причем ни для вектора ни для листа. Не учитывается время на аллокацию памяти для вектора, так-как делается резерв и не учитывается тот факт, что вставка в определенную позицию вектора (в данном случае в начало) медленная операция. Было бы честно сравнить время вместе с вызовом резерва и с операцией push_back. Вот результаты без вызора vector::reserve вообще и с push_back вместо insert для 100000000 элементов.
Ключевую роль играет кэширование при копировании данных в векторе. |
Автор: baldina 13.1.2014, 18:42 | ||
это входило в условия, см. выше
вставка в любую позицию вектора это медленная операция. при случайной позиции среднее число перемещений n/2 так что скорее вставка в конец не честна. и про это не было в условиях. если бы я выбрал середину, результат у вектора был бы лучше, но лишь в 2 раза. т.е. не принципиально так что считаю свой тест адекватным ;-) :off для тех кто не все понял с первого раза. тесты (наукообразно - эмпирический анализ) штука тонкая. что бы их проводить (и что бы интерпретировать готовые результаты) нужно учитывать самые различные факторы (все существенные). что бы потом не стыдиться своих скороспелых заявлений об ошибках в компиляторах, развенчании мифов и т.п. |
Автор: azesmcar 13.1.2014, 18:51 | ||||||
Ну тогда тем более вектор быстрее ![]()
Ну так и я об этом ![]()
В таком случае число перемещений эквивалентно числу числу вставляемых элементов. Если это то, что просил автор, тогда не совсем понятно с какой пьяни сравнивать контейнеры в контексте задачи, для которой один из них совершенно непригоден (это я про вектор) ![]() А вариант со вставкой в конец честен чем, что использует оба контейнера эффективно, а не использует заранее неэффективный метод одного и сравнивает с другим ![]() Добавлено через 8 минут и 44 секунды baldina
Ага, вижу. Невнимательно прочитал сперва. Ну тогда да, естественно лист будет быстрее. |
Автор: nonaot 14.1.2014, 22:50 |
Модератор: Сообщение скрыто. |
Автор: Artemon 21.2.2014, 21:59 |
Интересно, у кого-то бывает такое: находишь какой-то очень тонкий момент в коде, ставишь у себя в голове пометку, что так больше делать не нужно. Потом со временем забываешь и восстанавливая из памяти куски информации кажется, что именно так и нужно сделать. |
Автор: NoviceF 5.5.2014, 17:06 | ||
Похоже это какое-то свойство памяти.. у меня такое бывает безотносительно кода ![]() |
Автор: TarasProger 15.8.2015, 12:25 | ||||||||
Добавлено через 7 минут и 27 секунд
1. А что сложного его сделать? 2. Для этой целим можно сделать функцию find. А если бы программа была по-настоящему ООП-ной, то и перегрузить оператор [], чтоб индексировал по стригам. Релизация - тот же перебор. 3. Зачем сдесть STL? Добавлено через 9 минут и 43 секунды
Добавлено через 10 минут и 51 секунду
Добавлено через 14 минут и 1 секунду А, ну конечно, он предназначен для одного варианта. Вот только чем тогда if не устроил, что свич понадобился? |
Автор: TarasProger 15.8.2015, 12:42 |
А 35 не хотите? А то и 50. При этом все одного типа. |
Автор: TarasProger 15.8.2015, 13:05 | ||||
Рекурсия на пустом месте:
|
Автор: korol 4.3.2016, 13:10 |
Модератор: Сообщение скрыто. |
Автор: richardy 24.6.2020, 11:06 |
Thanks!! |
Автор: Эле7 1.7.2020, 14:57 |
Здравствуйте. Может кто - нибудь помочь мне с написанным кодом С++ по простой задачке на расчет дисперии и среднего значения. Всю голову сломала что не так с кодом и компилятором.... Добавлено через 30 секунд Код программы и задание могу выслать |
Автор: Zonanor 4.1.2021, 01:09 |
А там ни малейшего ###она нету же, как я знаю |