Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 23, средняя оценка - 4.65
HighPredator
5476 / 1842 / 343
Регистрация: 10.12.2010
Сообщений: 5,434
Записей в блоге: 3
#1

Coding style или нет - C++

09.02.2012, 19:56. Просмотров 2990. Ответов 60
Метки нет (Все метки)

Услышал сегодня от коллеги такую интересную вещь: есть блоки кода ограниченные командными скобками {}. Так вот, рекомендуется переменные, используемые в блоках и только в них, объявлять в таких блоках. Я например, как правило объявляю переменные в начале подпрограмм. Привычка. Вопрос такой: это чисто coding style рекомендация или есть какое-то практическое значение подобного действия?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.02.2012, 19:56     Coding style или нет
Посмотрите здесь:

Как разбить код на 2 функции: Coding и Decoding? - C++
#include <iostream> #include <vector> #include <map> #include <list> #include <fstream> using namespace std; ...

Где можго почитать о Coding Convention для C++ на русскос языке? - C++
Я не смог нагуглить.

Как найти текст в файле и возвратить 0 или 1 в зависимости от того,найдено или нет? - C++
bool fnd(char* fn,string stf) { string s; ifstream ifs(fn); while (!ifs.eof()) { getline(ifs,s); ...

Вывести True или False в зависимости от того, имеют три заданных целых числа одинаковую четность или нет - C++
Всем привет! Помогите, пожалуйста в решении задачи. Знаю, что задачи более,или менее лёгкие,но я в c++ почти ничего не смыслю, а лабы...

Опечатка или нет? - C++
class my_class { public: my_class() { a = b = 0; } my_class(constint...

C++11 в production, да или нет? - C++
Всем привет. Выбил все-таки разрешение юзать С++11 на работе, по мелочи, лямбды вместо предикатов, range-based-for, auto. Сегодня наш тех....

Палиндром или нет? - C++
Определить, является ли заданное натуральное число палиндромом, т.е. таким, десятичная запись которого читается одинаково слева направо и...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
10.02.2012, 14:34     Coding style или нет #46
AzaKendler, никогда не обнулял указатель в деструкторе. Потому что не для того деструктор предназначен, чтобы когда нам заблагорассудится вызывался. Он должен вызываться для одного объекта один раз, при уничтожении, и точка. Это как с const_cast. Он вроде как есть, и его даже вроде как можно использовать, но если из-за него программа свалится в рантайме, то программист сам дурак.
Ну и плюс к тому, в своих классах можно обо всём позаботиться (напихать ключей, которые будут говорить, закрыт ли файл, разорвано ли соединение, очищена ли память, и проверять всё это в деструкторе), но проблема в том, что мы чаще используем чужой код, а не собственный. И при этом надо знать, что деструктор не предназначен для вызова вручную, и что если такой вызов будет иметь и место и затем будет иметь место падение в рантайме, то программист снова сам дурак.
Bers
Заблокирован
10.02.2012, 14:36     Coding style или нет #47
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int GetLenth(int x1, int x2, int x3) 
{ 
    std::string str; str +=x1; str +=x2; str +=x3; 
    return str.size(); 
}
 
void func1 (int x1, int x2, int x3)
{
  int len = GetLenth(x1,x2,x3);
 
  // Здесь str нам больше не нужен. 
 
  for (i = 0; i < 1000000; i++)
    func2 (len);
}
Цитата Сообщение от Evg Посмотреть сообщение
Могут быть промежуточные значения
Ну вот, по поводу промежуточных значений...

Иногда, исключительно для читабельности, есть смысл завести промежуточный объект.
Но это переменные типа int какие нибудь...

Если же в качестве такого промежуточного объекта просится очень тяжелый объект - явно что то не в порядке в самой архитектуре.

Пример того, чего быть не должно:

MyClass a,b; //оч тяжелые объекты
...
MyClass c = a; a=b; b=c;

Пример того, что должно быть:
a.Swap(b); //перенацелятся лишь парочка указателей. Никакого копирования.

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


Цитата Сообщение от Evg Посмотреть сообщение
И в итоге из-за принципиальных соображений один нормально читаемый код в виде одной нормально читаемой функции превратится в десяток функций, в которых ориентироваться будет намного сложнее.
Этого не может быть. Есть только два варианта:
1. Весь код представляет собой монолитную размазню.
2. Код разбит на функции.

И если вспомогательных функций получился десяток другой, значит ваш "нормально читаемый код" просто хардкорно забил их текст внутри себя - монолитная чача.

Можно написать все в теле одной мега-раздутой функции. Можно разбить на десяток мелких.
Но само по себе "количество" кода либо не изменится, либо уменьшится, но только в случае разбиения на функции.
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
10.02.2012, 14:36     Coding style или нет #48
silent_1991, немного смысл утерян диалога. я выше в посте пометил почему началась эта тема.
конечно деструктор не нужно дергать дела без дела, а нужно только при необходимости/
А обнулять указатели надо по любому. поскольку в с++ delete нулевого указателя - это не ошибка, просто ничего не делается
а вот не обнуленного но уже ссылающегося на очищенную память - краш
Vourhey
Почетный модератор
6477 / 2252 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
10.02.2012, 14:45     Coding style или нет #49
Evg, Bers прав... Если функция настолько велика, что вынуждает объявлять переменные в ее середине (без явных на то оснований), то это уже "говнокод". От величины и сложности проекта не зависящий.
Цитата Сообщение от Evg Посмотреть сообщение
один нормально читаемый код в виде одной нормально читаемой функции првреатится в десяток функций
Лучше 10 вызовов функций с говорящими именами, чем простыня на 100 строк в одной функции, из которых 40 на комментарии.
Цитата Сообщение от Evg Посмотреть сообщение
то на время работы цикла память, отжираемая
* // экземпляром str, будет необоснованно болтаться как использованная
Это никак не скажется на работе программы. (если только в следующих вызовах не соберемся стек переполнить, что получится сделать немного быстрее)
Evg
Эксперт CАвтор FAQ
17546 / 5784 / 370
Регистрация: 30.03.2009
Сообщений: 15,931
Записей в блоге: 26
10.02.2012, 14:52     Coding style или нет #50
Цитата Сообщение от AzaKendler Посмотреть сообщение
но ты ведь вел речь об экономии памяти в стринге
string я использовал как пример экземпляра класса для наглядности. На его месте может быть любой самодельный класс, активно потребляющий память и работающий с файлами

Bers, вот тебе фрагмент отладчика gdb: файл infrun.c. См. функцию handle_inferior_event. Это одна большая логическая последоваттельность действий, которая потеряет всякую логику, будучи искусственно разбитой на маленькие запчасти

Добавлено через 1 минуту
Цитата Сообщение от Vourhey Посмотреть сообщение
Это никак не скажется на работе программы. (если только в следующих вызовах не соберемся стек переполнить, что получится сделать немного быстрее)
Я уже говорил, что string - условность. Это может быть экземпляр произсольного класса, который отожрал 10 мегабайт динамической памяти и которая освободится только при удалении объекта
Bers
Заблокирован
10.02.2012, 14:55     Coding style или нет #51
Цитата Сообщение от AzaKendler Посмотреть сообщение
А обнулять указатели надо по любому. поскольку в с++ delete нулевого указателя - это не ошибка, просто ничего не делается
а вот не обнуленного но уже ссылающегося на очищенную память - краш
Вот я так и не определился с мыслью: ошибка это, или нет - удалять по нулевому указателю.

Но вот по опыту скажу, что очень рад, что не нулил указатели после удаления. Ибо повторное удаление у меня возникало исключительно из-за программных ошибок.
Стало быть, я об этих ошибках узнавал, и исправлял.

А если бы программка тихо промолчала - стало быть, и не узнал бы я, что у меня прокрался баг.

Из этих соображений, решил я ставить ассерт перед удалением. И ежели указатель уже ноль - стало быть в дебаге мне мой код об этом поведует. А в релизе сохранит работоспособность.
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
10.02.2012, 15:01     Coding style или нет #52
Цитата Сообщение от Evg Посмотреть сообщение
который отожрал 10 мегабайт динамической памяти и которая освободится только при удалении объекта
если это самописный класс, то уже на совести того кто его писал предусмотреть аналог clear() и возможность очистки ДО удаления при выходе из области видимости.
Это уже более философский вопрос, касающийся того "а что за человек писал код".

Добавлено через 3 минуты
Bers, ну если ты предпочитаешь так проверяться то да. ты практикующий постоянно судя по всему. к тебе можно прислушаться.
но при тестах ты можешь и не найти ту ошибку которая приводит к крашу и не обнаружить какие то петли и повторные вызовы. это может произойти у клиента. ну а если будет 0, то будет работать пока ты готовишь апдейты или проводишь доп тесты.
ну это такая фантазия

я же лишь черпаю информацию из книг и форума. в книгах рекомендуют нулить.

Добавлено через 1 минуту
Цитата Сообщение от Bers Посмотреть сообщение
И ежели указатель уже ноль
все таки нулишь?
Evg
Эксперт CАвтор FAQ
17546 / 5784 / 370
Регистрация: 30.03.2009
Сообщений: 15,931
Записей в блоге: 26
10.02.2012, 15:04     Coding style или нет #53
Цитата Сообщение от AzaKendler Посмотреть сообщение
все таки нулишь?
Он нулит его только для того, чтобы поймать ситуацию повторного вызова деструктора. И это правильный способ.
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
10.02.2012, 15:05     Coding style или нет #54
Цитата Сообщение от Bers Посмотреть сообщение
Вот я так и не определился с мыслью: ошибка это, или нет - удалять по нулевому указателю
думаю не ошибка. указатель может быть установлен в 0 в конструкторе и ждать некой функции Init();
если инит не вызван то указатель так и будет 0, и в деструкторе будет delete 0. если инит отработает то будет что то удалено из
памяти в деструкторе как и задумывалось
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
10.02.2012, 15:05     Coding style или нет #55
AzaKendler, clear в том же стринге память не очищает. В векторе, например, тоже. Т.е. ни стринг, ни вектор вообще никогда не уменьшают размера. Пример:
http://liveworkspace.org/code/4df806...11d68864746f5c
Напомню, что capacity возвращает количество элементов, которое контейнер может вместить без очередного выделения памяти.
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
10.02.2012, 15:10     Coding style или нет #56
silent_1991, тогда resize(0). за клиар сорри. спасибо за уточнения уж если писать то точно.
имел ввиду принцип очистки до удаления. напутал функцию
Bers
Заблокирован
10.02.2012, 15:11     Coding style или нет #57
Цитата Сообщение от AzaKendler Посмотреть сообщение
все таки нулишь?
Есть два режима: дебаг, и релиз.
Дебаг - это версия для отладки. Релиз - это версия для клиента.

В дебаге ассерты срабатывают. В релизе, код проверок будит выброшен препроцессором и не будет скомпилирован.

Перед удалением у меня стоит ассерт, который сработает, если указатель нулевой.
А после удаления, соответственно, зануляет указатель.

Таким образом, в дебаге у меня будет проверка на попытку двойного удаления.
А в релизе никаких проверок вообще уже не существует. Но так как указатели зануляются, то попытка двойного удаления вреда не нанесет.

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

Тут есть свои нюансы: например, если объект в принципе имеет право "не выделять динамическую память". Допустим, при создании, он ещё пустой, и его указатель нулевой. То.. он имеет право делетить нулевой указатель.
А если объект при создании автоматически выделяет память - тогда не имеет.
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
10.02.2012, 15:17     Coding style или нет #58
AzaKendler, clear и есть resize(0). Невозможно уменьшить размер выделенной в строке памяти извне. Даже reserve(0) не поможет.

Добавлено через 1 минуту
Вру.
Можно так:
C++
1
2
str.resize(0);
str.reserve(0);
Добавлено через 1 минуту
Но это только со строкой. Вектор совершенно отказывается "расти вниз".
Bers
Заблокирован
10.02.2012, 15:18     Coding style или нет #59
silent_1991

C++
1
void ClearStr(std::string& obj) {   std::string tmp; tmp.swap(obj); }
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.02.2012, 15:19     Coding style или нет
Еще ссылки по теме:

Полиндром или нет? - C++
#include &lt;iostream&gt; #include &lt;cstdio&gt; using namespace std; int main() { setlocale(LC_ALL,&quot;Russian&quot;); bool otvet; int i;...

симафор или нет? - C++
ПРивет всем! написал программу для следующего задания с использованием симафора: Написать программу, создающую два потока. Оба...

Посмотрите правильно или нет. - C++
Четырехугольник ABCD задан координатами своих вершин на плоскости: A(Xa,Ya),B(Xb,Yb),C(Xc,Yc) , D(Xd,Yd).Проверить являетса ли он выпуклым....

Многоугольник выпуклый или нет? - C++
Помогите пожалуйста написать функцию для проверки выпуклости многоугольника, заданный на плоскости перечислением координат его вершин в...

Цикл: правильно или нет? - C++
Знающие люди, подскажите пожалуйста... Есть такая задачка: http://pic.ipicture.ru/uploads/090209/FqJj1Wz56M.jpg необходимо вычислить...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
10.02.2012, 15:19     Coding style или нет #60
silent_1991, чтож остается только swap с пустым классом
Yandex
Объявления
10.02.2012, 15:19     Coding style или нет
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru