Russian Qt Forum
Ноябрь 21, 2024, 23:53 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: c vs c++  (Прочитано 19289 раз)
Day
Частый гость
***
Offline Offline

Сообщений: 290


Просмотр профиля
« Ответ #15 : Ноябрь 10, 2019, 14:36 »

Пример, конечно, крайне упрощенный. В самом деле дело было так. Был класс, и он работал с файлом. И много там было всего еще. Конструктору передавалось имя. А файла могло и не быть. И тут бы самое лучшее - вернуть что-то, говорящее - нету твоего файла. NULL, например. Потому что без толку экземпляр городить. И даже память на переменные класса нету смысла выделять. Конечно, можно это дело закостылить. Переменную, говорящую о неудаче. Потом взять ее геттером, сказать экземпляру delete и спокойно работать дальше. Но эстетически это выглядит костылем. Как и try.
К тому же, этот класс пользуется в нескольких местах, раскиданных по кодам. Тоже выход не сложен. Обернуть функцией. (не методом!) Но осадочек все равно остается....Улыбающийся
Записан
Day
Частый гость
***
Offline Offline

Сообщений: 290


Просмотр профиля
« Ответ #16 : Ноябрь 10, 2019, 14:42 »

Цитировать
почему же никто кроме вас не озабочен этой проблемой?
Да нельзя сказать, что уж очень я озабочен. Вы предложили поболтать, я и вспомнил эпизод. Какие там заботы?! Всегда можно вставить кусок на чистом С (слава Богу, пока это не запрещено) или вот костылик наваять. Поле для творчества немерянное!:)
Записан
Azazello
Самовар
**
Offline Offline

Сообщений: 103


Просмотр профиля
« Ответ #17 : Ноябрь 10, 2019, 14:51 »

Пример, конечно, крайне упрощенный. В самом деле дело было так. Был класс, и он работал с файлом. И много там было всего еще. Конструктору передавалось имя. А файла могло и не быть. И тут бы самое лучшее - вернуть что-то, говорящее - нету твоего файла. NULL, например. Потому что без толку экземпляр городить. И даже память на переменные класса нету смысла выделять. Конечно, можно это дело закостылить. Переменную, говорящую о неудаче. Потом взять ее геттером, сказать экземпляру delete и спокойно работать дальше. Но эстетически это выглядит костылем. Как и try.
К тому же, этот класс пользуется в нескольких местах, раскиданных по кодам. Тоже выход не сложен. Обернуть функцией. (не методом!) Но осадочек все равно остается....Улыбающийся

Скажу про себя. Уж очень часто, разрабатываю прогу на с++ подсознательно пытаюсь её сделать максимально производительной. Там где воооооооооообще это не нужно, не стоит и так далее и так далее......

Скорее всего ваш класс не Pimpl. Что мешает создать его в стеке, что ничего не стоИт в плане производительности.
Вариант 2:  функцию static создать (аля класс фактори), которая возвращает объект если файл есть (либо прочитанным файлом). Аля:
Код:
      class FileParser {
            FileParser(char*) //какие либо бинарные данные в вашем виде, тип не важен.
             bool isValid() const noexcept;
             static FileParser file(const std::string& fName);
       }

Применение:

Код:
   FileParser parser = FileParser::file("MyFavorFile");
   if (hasError())
       cout << parser.errString;

Это конструкция примитивна, но действенна - мы избавляемся от ошибок инициализации в конструкторе класса и добавляем проверки при передачи в сам объект и не будет выделение памяти под файл.
Понятно, это RAI конструкция, возможна и pointer или unique_ptr. Там проще - nullptr - нету файла. Но кого это интересут, дабаги сообщения наше всё.

Но даже это не стоит той работы (кроме, конечно, удовлетворения своим кодом). Чтение файла в тысячи (минимум) раз медлениее, чем самое ваше медленное решение.
« Последнее редактирование: Ноябрь 10, 2019, 15:37 от Azazello » Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #18 : Ноябрь 10, 2019, 14:51 »

Пример, конечно, крайне упрощенный. В самом деле дело было так. Был класс, и он работал с файлом. И много там было всего еще. Конструктору передавалось имя. А файла могло и не быть. И тут бы самое лучшее - вернуть что-то, говорящее - нету твоего файла. NULL, например. Потому что без толку экземпляр городить. И даже память на переменные класса нету смысла выделять. Конечно, можно это дело закостылить. Переменную, говорящую о неудаче.

std::optional для этого случая подошло бы?
Записан

Пока сам не сделаешь...
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #19 : Ноябрь 10, 2019, 16:17 »

Ну, вот такой простой пример (и не очень надуманный)

Проверять имеет смысл только когда выделяются какие-то большие буфера, если после пары гигов нет памяти на инт, то ничего не поделать, придется упасть с std::bad_alloc.
В этих случаях можно обойтись маллоком и проверить по-старинке.
В остальных 99% случаев просто забить.
На самом деле, в том же Линуксе маллок никогда не вернет nullptr и new не тровнет, там по умолчанию включен memory overcommitment. То есть программу убьют когда вы попытаетесь в эту память записать, а не на выделении.
Вывод - ловить нехватку памяти надо только там где это можно нормально обработать, в остальных случаях - забить.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #20 : Ноябрь 10, 2019, 16:19 »

Не, ну тут я вообще ничего не осилил, даже Ваш пример. В упор не понимаю эту конструкцию.
В C API считается хорошим тоном проверять все указатели на null. Как достичь того же на плюсах? Просто сравнение this нехорошо, о чем шланг и говорит.

Это плохой и негодный код.
...
Вот опять очередная попытка обмануть компилятор и его разработчиков.
...
...но вы же не читали
Хорошо, пусть так, но согласитесь - последующий совет выглядит совсем куцым по сравнению с уничтожающей критикой, да и очевиден без всякого чтения
Делайте статичным сишным методом. То есть оставляйте как было.
Улыбающийся
Таких мест много сотен, всякий раз рихтовать вызывающего трудоемко, да и короткая конструкция заменяется на более длинную. А если попробовать так

Код
C++ (Qt)
template <class T>
bool IsNull( const T * a ) { return !a; }

Да, множ наследование все равно не проверит, ну и бог с ним, это редкость. Что еще плохого? Покритикуйте

Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #21 : Ноябрь 10, 2019, 16:33 »

Код
C++ (Qt)
template <class T>
bool IsNull( const T * a ) { return !a; }

Да, множ наследование все равно не проверит, ну и бог с ним, это редкость. Что еще плохого? Покритикуйте
А что это решает? Улыбающийся
Записан
Azazello
Самовар
**
Offline Offline

Сообщений: 103


Просмотр профиля
« Ответ #22 : Ноябрь 10, 2019, 17:17 »


Проверять имеет смысл только когда выделяются какие-то большие буфера, если после пары гигов нет памяти на инт, то ничего не поделать, придется упасть с std::bad_alloc.
В этих случаях можно обойтись маллоком и проверить по-старинке.
В остальных 99% случаев просто забить.
На самом деле, в том же Линуксе маллок никогда не вернет nullptr и new не тровнет, там по умолчанию включен memory overcommitment. То есть программу убьют когда вы попытаетесь в эту память записать, а не на выделении.
Вывод - ловить нехватку памяти надо только там где это можно нормально обработать, в остальных случаях - забить.

Вопрос к уровню рассуждений. На каком мы уровне?
Можно рассуждать о скорости: v = расстояние/на время. В квантовой теории формула преображается.

Большой проект с выделением огромного кол-ва памяти? Совершенно другой подход, который мы здесь не  обсуждаем. В конкретном случаем мы не Oracle DB пишем. Хотя, возможно, есть здесь люди, которым надо большие объемы. Там сразу идёт по дефолту "менеджер памяти" свой и в этих рассуждениях они не участвуют. Аля пул потоков или аля стек. Не знаю как правильно аналогию провести.

Ну кто здесь парится про стек, который занимает 2 метра. Любое падение в стеке- ошибка рекурсии.

Это я к чему, Авварон. Надо на одном уровне находится, хотите другой - либо его красиво поднимайте в новой теме, либо.... Ну, не знаю как.


Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #23 : Ноябрь 10, 2019, 17:22 »

Мужик, я нихрена не понял что ты мне сказал
Записан
Azazello
Самовар
**
Offline Offline

Сообщений: 103


Просмотр профиля
« Ответ #24 : Ноябрь 10, 2019, 17:33 »


Эхехех
Как то так:
1-й класс: 3-5 - задача не имеет решение.
4-й класс: 3-5 равное -2.

Суть не в том, что кто-то лучше знает, кто-то хуже, просто на каких-то эпатах нужно рассуждать на "нужном уровне".
Вам же не кажется глупым выражением: "Солнце встало".

Та этож бред! Земля вращается вокруг солнца, оно не может встать.

Сомневаюсь, что вы будете выносить мозги своим родным, доказывая что это утверждении не верно.

НО!!!!!!!!!!! Видео мне пондравилось.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #25 : Ноябрь 10, 2019, 19:16 »

Azazello, понятнее-то не стало. Я тоже НХНП. Веселый
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Azazello
Самовар
**
Offline Offline

Сообщений: 103


Просмотр профиля
« Ответ #26 : Ноябрь 10, 2019, 19:42 »

Azazello, понятнее-то не стало. Я тоже НХНП. Веселый

Ну хорошо.
Митинг/оперативка/собрание.
Руководитель: написать ауторанер для DVD. Типа инстал что-то, красивые обои.
И тут встаёт чел: Предлагаю использовать самые передовые технологии! Будем писать на С+17 с использование последних фитч!
Все остальные ( в мыслях): Ну дебил, митинг затягивает, дадим Коляну, он за сегодня напишет.

Вариант 2:
Митинг/оперативка/собрание.
Руководитель: мы сегодня будем разрабатывать новую БД, которая порвёт рынок!
И тут встаёт чел: Предлагаю использовать самые передовые технологии! Создадим свой менеджер памяти и файловой системой!
Все остальные ( в мыслях): Ну блин попали, о чём он?

Подход разный, просто подход разный даже на уровне одного приложения я переключаюсь на разные уровни владения языком, там где это нужно и там где это не впало.

Да блин, что тут объяснять: когда начинаем строить дом, нефиг цвет занавесок обсжудать.
Когда дом построили и выбираем занавески, нефиг фундамент обсуждать.
« Последнее редактирование: Ноябрь 10, 2019, 19:52 от Azazello » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #27 : Ноябрь 10, 2019, 22:59 »

Я как-то пришел на собеседование студентом в контору где меня срезали на том что я не привык проверять аллокацию памяти. Эти чувачки писали if (ptr) после ptr = new QTreeWidgetItem. Nuff said.
Записан
Azazello
Самовар
**
Offline Offline

Сообщений: 103


Просмотр профиля
« Ответ #28 : Ноябрь 10, 2019, 23:42 »

В C API считается хорошим тоном проверять все указатели на null. Как достичь того же на плюсах? Просто сравнение this нехорошо, о чем шланг и говорит.

Да в том же Си есть фунции с суффиксом s (secure), которые делают доп проверки "на взлом". Хош вызывай небезопасную, хош безопасную. Это я к чему  - если вы уже точно знаете, что ваши данные валидны, зачем каждый раз вызывать s.

Если брать аналогию с C++, то тут даже проще. Половину ресурсов вы можете создать в конструкторе (нужном инициализваторе) и больше внутри класса не парится на проверку. Либо (для примера) pimp, где приватный класс точно знает, что все данные у него валидны - проверка во внешнем классе. (опять же, это как пример).

Так что я думаю тут плюсы выигрывают в плане проверок и краткости кода.
Да в конце концов можно использовать отложенную инициализацию.
И проверка if превращается в getPointer, где поинтер возвращает обертку над данными, которая всегда валидна для использования, даже если данных нет.

Или глобально в классе, isValid...
Какие то у вас не транзитивные классы. Ну очень. Я не знаю, что это означает, но звучит круто.

Классический вызов функции Си:

Код:
hw = someOperation(d,&e)

if (!hw)
   return;

if (hw == someErr) {
   printErr(sfsfdsfsfd);
   someOperationFree(e);
   return;
}

ещё 57 проверок
типа......

if (hw == someErr) {
   printErr(sfsfdsfsfd);
   someOperationFree(e);
   return;
}  

Код

и в конце
someOperationFree(e);

Даже определение std::unique_ptr(e,someOperationFree) очень упрощает этот сишный код
« Последнее редактирование: Ноябрь 11, 2019, 00:20 от Azazello » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #29 : Ноябрь 11, 2019, 06:34 »

Ну, вот такой простой пример (и не очень надуманный)
Код:
int *a;
a = malloc(N*sizeof(int));  // C
if (a==NULL) ...
                        // C++
a = new int[N];  // Может выброситься исключение. Только так можно поймать...
                        // Приходится оборачивать
try {
  a = new int[N];
} catch {
   ...
}
         // Но меня коробит...
Очень смутно, но когда-то видел форму new которая возвращает null вместо выброса исключения. Что-то типа
Код
C++ (Qt)
a = new (std::nothrow) int[N];
Но могу путать
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.191 секунд. Запросов: 22.