On 09/18/2012 02:56 PM, Шебеко Евгений wrote:
> "Андрей Александреску: Современное проектирование на С++" — книга скорее > вредная, чем полезная. > Она производит сильное впечатление, у читателя сразу случается приступ шаблонизма. > Хотя сам Александреску призывает разумно использовать шаблоны и не заменять ими > наследование.
Здравствуйте, Шебеко Евгений, Вы писали:
ШЕ>Для динамических объектов можно использовать смарт указатели. Например: shared_ptr (boost::shared_ptr, std::shared_ptr) или std::auto_ptr
std::auto_ptr устарел. в С++03 лучше использовать boost::scoped_ptr или boost::unique_ptr
ШЕ>Предпочтительнее использовать shared_ptr<>, т.к. внутри него есть счётчик ссылок, что позволяет его безопасно копировать и хранить в контейнерах.
ниразу не предпочтительнее. он потокобезопасный и потому очень медленный, так что предпочтительнее — std::unique_ptr.
к томуже в большинстве случаев общее владение объектом не нужно.
On 09/18/2012 02:51 PM, Шебеко Евгений wrote:
> Вот такой код: > > > char q[1024]; > strcpy(q,"select p.street from payers as p, pl_accounts as a where a.orgid="); > strcat(q, vOrgID.at(lsOrganisation.GetCurSel()).GetString()); > strcat(q," and p.id=a.payerid group by p.street order by p.street;"); > if(!cur.Prepare(q)) > > > > Должен выглядеть так:
Ещё очень удобно и правильно использовать вектора для таких временных буферов:
std::vector< char > q(1024);
strcpy(&q[0],"select p.street from payers as p, pl_accounts as a where a.orgid=");
strcat(&q[0], someVal);
strcat(&q[0]," and p.id=a.payerid group by p.street order by p.street;");
Также можно это использовать для временных буферов для вызова C API,
ну и конечно же в даном примере можно подтянуть и boost::printf и многое другое.
В современной версии стандартна так можно использовать и std::string вместо
std::vector.
Только один недостаток: лишняя нагрузка на хип и может быть лишная точка
синхронизации в многопоточных приложениях.
> Вопрос-то не в том, а в том, зачем нужны советы от Шебеко.
ПО-моему так всё очень правильно и здорово. Не важно, от кого советы, важно,
чтобы были правильные. А еси повторяются -- не страшно, лишний раз кто-то
прочитает -- хуже не будет.
Здравствуйте, MasterZiv, Вы писали:
MZ>ПО-моему так всё очень правильно и здорово. Не важно, от кого советы, важно, MZ>чтобы были правильные. А еси повторяются -- не страшно, лишний раз кто-то MZ>прочитает -- хуже не будет.
Да нет, просто в книге все собрано и ссылки на Мейерса, Саттера, Страуструпа и других, если кого какая тема заинтересовала и хочется поподробнее. И книга сама тонюсенькая, чуть больше 200 страниц.
Здравствуйте, MasterZiv, Вы писали:
>> Хотя сам Александреску призывает разумно использовать шаблоны и не заменять ими >> наследование.
MZ>+1. Очень всё правильно.
Что правильно-то? Если нужен статический полиморфизм (времени компиляции), а не динамический (времени выполнения), то как раз нужно использовать шаблоны, а не наследование.
Здравствуйте, Шебеко Евгений, Вы писали:
ШЕ>Сейчас приходится собеседовать много новичков. ШЕ>Заметил что ничего в жизни не меняется. ШЕ>Даже люди с опытом работы в крупных наступают на те же грабли, на которые наступал я в своё время.
ШЕ>Хочу представить такие рекомендации новичкам в C++. Для того чтобы вы могли повысить свой уровень ШЕ>ну и хотя бы лучше пройти собеседование.
ШЕ>Если кто желает что-то добавить — пожалуйста. ШЕ>Только просьба придерживаться таких соглашений:
ШЕ>- Это должны быть грабли, на которые наступают регулярно. ШЕ>- Краткое описание проблемы и методы её решение. ШЕ>- Обяснение причин. ШЕ>- Проверенный (скомпилированный) пример кода.
соседушко по офису, дебил и неряха, десятилетиями пишет код вида:
....
int * arr = new int[some_size];
if (laja)
return;
...
delete [] arr;
Ошибка — тривиальная и дебильная, как и мой сосед: неиспользование РАИИ приводит к тому, что любой ресурс, требующий освобождения (с памятью — это самое простое)
у этого имбецила утекает в любой более/менее сложной функции, где есть какие-то вложенные блоки.
Спасает только статический анализатор, который заваливает этого ЛОШАРУ горами сообщений.
Ес-но, фикся, кретин плодит новое говно и получает по тупой харе от анализатора и т.д. — имя этому процессу — бесконечность.
Of course, the code must be complete enough to compile and link.
Здравствуйте, Abyx, Вы писали:
ШЕ>>Для динамических объектов можно использовать смарт указатели. Например: shared_ptr (boost::shared_ptr, std::shared_ptr) или std::auto_ptr A>std::auto_ptr устарел. в С++03 лучше использовать boost::scoped_ptr или boost::unique_ptr
Вот кстати пример того, почему лучше все-таки читать советы настоящих, а не доморощенных гуру.
ой, я не заметил, что ты уже писал про такое. но, короче, когда человек пишет в стиле "назад в 1982 к С с классами" — это его ежедневный "паттерн" — неспособность освободить ресурсы.
Of course, the code must be complete enough to compile and link.
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>ой, я не заметил, что ты уже писал про такое. но, короче, когда человек пишет в стиле "назад в 1982 к С с классами" — это его ежедневный "паттерн" — неспособность освободить ресурсы.
Здравствуйте, Abyx, Вы писали:
A>если С++03 — зачем функтор если достаточно функции
насколько я знаю фуктор подставляется в параметр шаблона как тип, то есть чистый compile-time, а функция как указатель на семейство функций со всеми вытекающими.
А как C++98 и C++03 отличаются в этом месте?
Здравствуйте, Шебеко Евгений, Вы писали:
ШЕ>Каждый второй кандидат на предложение отсортировать массив, предлагает сортировку пузырьком!!! ШЕ>Только два кандидата, с помощью гугла, смогли дать более-менее рабочий код с использованием std::sort()
А я знаю сортировку выбором!
Если бы мне предложили отсортировать контейнер, то я специально использовал бы сортировку выбором с использованием станалртных алгоритмов!
ШЕ>Вот тестовое задание, которое вводит в ступор всех кандидатов:
Здравствуйте, Abyx, Вы писали:
A>Здравствуйте, Шебеко Евгений, Вы писали:
ШЕ>>std::hash_map<>,std::hash_set<>
A>нету таких классов в std
ШЕ>>//предикат ШЕ>>struct human_pr ШЕ>>{ ШЕ>> inline bool operator()(const human_t& a,const human_t& b) const ШЕ>> { ШЕ>> if(a.last_name!=b.last_name)return a.last_name<b.last_name; ШЕ>> return a.first_name<b.first_name; ШЕ>> } ШЕ>>}; ШЕ>>
A>если С++03 — зачем функтор если достаточно функции A>если С++ — должна быть лямбда.
К функции вы не сможете применить адаптеры, как, например, std::not1.
Лямбда выражения целесообразно применять, лишь когда они используется в какой-то локальной области кода. Если же они захватывают локальные переменные, а ич функциональность должна использоваться в нескольких местах кода и единиц трансляции, то лучше использовать функциональные объекты.
Здравствуйте, Piko, Вы писали:
A>>если С++03 — зачем функтор если достаточно функции
P>насколько я знаю фуктор подставляется в параметр шаблона как тип, то есть чистый compile-time, а функция как указатель на семейство функций со всеми вытекающими.
да, в каких-то версиях MSVC именно так (хз как в MSVC11), а в g++ вроде функция инлайнится, IIRC
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>странно, что ты не понял — я не об особенностях определенной реализации С++ говорю, а о том, что люди на С++ пишут, как будто у них С или что похуже.
Мне в самом деле стало интересно, с самого ли начала в C++ или C с классами был деструктор.
А вот по поводу "как будто у них С" несогласен. На C, когда в функции выделяются русурсы, return как правило один — в конце. (Или его вообще нет, если функция ничего не возвращает.)
Здравствуйте, Abyx, Вы писали:
A>>>если С++03 — зачем функтор если достаточно функции P>>насколько я знаю фуктор подставляется в параметр шаблона как тип, то есть чистый compile-time, а функция как указатель на семейство функций со всеми вытекающими. A>да, в каких-то версиях MSVC именно так (хз как в MSVC11), а в g++ вроде функция инлайнится, IIRC
функция конечно может инлайнится — и она скорей всего нормально инлайнится во многих версиях msvc, и gcc, но у функтора намного больше шансов.
написать лишние двадцать буковок для функтора — не проблема, большой смысловой нагрузки они не несут, ошибится в них трудно
Здравствуйте, Сыроежка, Вы писали:
A>>если С++03 — зачем функтор если достаточно функции A>>если С++ — должна быть лямбда. С>К функции вы не сможете применить адаптеры, как, например, std::not1.
1. есть std::ptr_fun.
2. к human_pr not1 не применишь, во-первых он бинарный, во-вторых он не определяет argument_type.
3. нафига not1 в данной конкретной задаче?
С>Лямбда выражения целесообразно применять, лишь когда они используется в какой-то локальной области кода. Если же они захватывают локальные переменные, а ич функциональность должна использоваться в нескольких местах кода и единиц трансляции, то лучше использовать функциональные объекты.
Я удивлён, но мысль у тебя верная, браво!
Вот только к обсуждаемому примеру не относится, там лямбду использовать целесообразно
Re[2]: Копирующий конструктор и копирующий operator= по умолчанию.
Здравствуйте, Шебеко Евгений, Вы писали:
ШЕ>Если класс не содержит явного копирующего конструктора или operator=, то они создаются неявно. ШЕ>Об этом надо помнить.
ШЕ>Допустим у нас есть класс, который содержит в себе указатель на свой буффер.
[тут был код очередного класса буфера]
Для меня new вне конструктора умного указателя (std::shared_ptr, std::unique_ptr или их аналогов из Boost) — признак плохого кода.
В прикладном коде new/delete не нужен, для буфера есть std::vector<char> или его суженный аналог: