Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Применяется const в параметрах функции? 
:(
    Опции темы
hoz
Дата 3.9.2014, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 27.6.2013

Репутация: нет
Всего: нет



 Я призадумался сегодня. Вот ведь есть модификатор const. В самих функциях и классах он применяется. А вот в параметрах функции применяется или нет? Я заметил, что не часто.
 Хотя по сути,  если параметр функции не изменяется, то можно было бы и применить. Так?
 Или это не обязательно?
PM MAIL   Вверх
baldman88
Дата 4.9.2014, 07:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 210
Регистрация: 18.1.2009

Репутация: 1
Всего: 7



Цитата(hoz @  3.9.2014,  19:14 Найти цитируемый пост)
Я заметил, что не часто.

Почему же это. Посмотрите исходники хороших open source проектов. Применение const в параметрах помогает избежать трудновылавливаемых ошибок.
Хотя есть люди, которые имеют совершенно противоположное мнение и считают, что применение const в параметрах это зло.
PM MAIL   Вверх
math64
Дата 4.9.2014, 08:22 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Цитата(baldman88 @  4.9.2014,  07:51 Найти цитируемый пост)
Хотя есть люди, которые имеют совершенно противоположное мнение и считают, что применение const в параметрах это зло. 

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

Это сообщение отредактировал(а) math64 - 4.9.2014, 08:23
PM   Вверх
borisbn
Дата 4.9.2014, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(hoz @  3.9.2014,  19:14 Найти цитируемый пост)
Я заметил, что не часто.

Наоборот. Применяется. И повсеместно. Если в каких-то исходниках можно добавить const, но его там нет, то это - плохие (или очень старые, как заметил math64).
Ещё один момент - в языке Си (не путать с Си++) до стандарта С99 модификатора const просто не было, А огромное количество исходников написано именно на нём. Они прекрасно (ну... почти) компилируются современными компиляторами Си++, и их просто никто не хочет модифицировать. Работает - и ладно.

Это сообщение отредактировал(а) borisbn - 4.9.2014, 12:56


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
kemiisto
Дата 4.9.2014, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 5
Всего: 160



Цитата(borisbn @  4.9.2014,  11:55 Найти цитируемый пост)
А огромное количество исходников написано именно на нём

А ещё немалое количество исходников написано на адской смеси C/C++, в которой вообще что угодно можно увидеть. По сабжу же, конечно, достаточно будет процитировать владыку нашего Мейерса smile 
Цитата
Правило 3: Везде, где только можно, используйте const

и отослать ТСа за подробностамя к фолианту Мейерс - Эффективное использование C++, 3-е изд. (2006). smile 


--------------------
PM MAIL WWW GTalk Jabber   Вверх
hoz
Дата 6.9.2014, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 27.6.2013

Репутация: нет
Всего: нет



Цитата(baldman88 @  4.9.2014,  07:51 Найти цитируемый пост)
Почему же это. Посмотрите исходники хороших open source проектов

Где бы их увидеть...

Я чего спросил. Вот, например, у меня метод:
Код

int      fOrderSend (string fs_Symbol, int fi_Type, double fd_Lot, double fd_Price, int fi_Slip, double fd_SL, double fd_TP,
                           int fi_Magic = 0, string fs_Comm = "", datetime fdt_Expiration = 0, color fc_Arrow = CLR_NONE);


Получается правильно его сделать так выходит, судя по вышенаписанному.. :
Код

int      fOrderSend (const string fs_Symbol, const  int fi_Type, const  double fd_Lot, const  double fd_Price, const int fi_Slip, double fd_SL, double fd_TP,
                           iconst  nt fi_Magic = 0, const  string fs_Comm = "", const  datetime fdt_Expiration = 0, const  color fc_Arrow = CLR_NONE);

Верно? Получается, что методы "удлинняются"
PM MAIL   Вверх
borisbn
Дата 6.9.2014, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



11 параметров в функции - уже плохо. А вообще - принято простые типы (int, double, etc.) передавать по значению, а объекты (string, datetime, etc.) - по константной ссылке. Т.о. твой метод д.б. таким
Код
int      fOrderSend (const string & fs_Symbol, int fi_Type, double fd_Lot, double fd_Price, int fi_Slip, double fd_SL, double fd_TP,
                           int fi_Magic = 0, const  string & fs_Comm = "", const  datetime & fdt_Expiration = 0, const color & fc_Arrow = CLR_NONE);

Цитата(hoz @  6.9.2014,  14:53 Найти цитируемый пост)
Получается, что методы "удлинняются" 

и ?
Код пишется один раз, а читается - много.
Цитата(hoz @  6.9.2014,  14:53 Найти цитируемый пост)
Где бы их увидеть...

github, sourceforge


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
baldina
Дата 6.9.2014, 20:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(hoz @  6.9.2014,  14:53 Найти цитируемый пост)
Получается правильно его сделать так выходит, судя по вышенаписанному

нет. параметры передаются по значению, поэтому ставить перед ними const - тавтология. так что в упомянутой функции fOrderSend const вообще не нужен.
const имеет смысл, только если параметр передается по ссылке или указателю, что бы избежать лишнего копирования. обычно это делается для сложных типов (которые длиннее указателя).  тогда функция превращается в то, что показал borisbn.
PM MAIL   Вверх
hoz
Дата 6.9.2014, 23:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 27.6.2013

Репутация: нет
Всего: нет



Цитата(baldina @  6.9.2014,  20:54 Найти цитируемый пост)
нет. параметры передаются по значению, поэтому ставить перед ними const - тавтология. так что в упомянутой функции fOrderSend const вообще не нужен.

Согласен. Я это и хотел отписать. Какой резон писать const перед переменной, которая передаётся по ссылке и модифицируется, а после возвращается по ссылке из функции в вызывающую.
PM MAIL   Вверх
sQu1rr
Дата 8.9.2014, 00:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(hoz @  6.9.2014,  23:50 Найти цитируемый пост)
Какой резон писать const перед переменной, которая передаётся по ссылке и модифицируется, а после возвращается по ссылке из функции в вызывающую. 

щито?  smile 
PM MAIL Skype GTalk   Вверх
borisbn
Дата 8.9.2014, 00:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Полностью согласен с предыдущим оратором. Ни разу не понял этой фразы


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Lukkoye
Дата 8.9.2014, 11:44 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: нет
Всего: 1



Цитата(baldina @  6.9.2014,  20:54 Найти цитируемый пост)
нет. параметры передаются по значению, поэтому ставить перед ними const - тавтология.


Вы ошибаетесь.

Квалификатор const гарантирует, что имя будет использовано только для чтения.

Это важно не только для читабельности, и оптимизации (древним компиляторам помогало оптимизировать код), но так же является важным требованием для строгих гарантий.

Строгая гарантия - гарантия, что в случае, если процедура зафейлится, данные не будут утеряны:

Код

void foo( const int val  )
{
     val = calculate(data);  //нельзя! Строгая гарантия - исходные данные не будут повреждены в случае провалов

     ...

     //здесь полетели исключения, и отработало восстановление после паники - откат транкзации
}



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

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


В книжках рекомендуют использовать const по максимуму: везде, где только возможно.

Я бы дополнил эту рекомендацию - если без особых затрат, вы можете предоставить строгие гарантии - сделайте это. 


От того что вы напишите лишний раз const для аргумента, который является значением - не переломаетесь.

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



Это сообщение отредактировал(а) Lukkoye - 8.9.2014, 11:47
PM MAIL   Вверх
baldina
Дата 8.9.2014, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(Lukkoye @  8.9.2014,  11:44 Найти цитируемый пост)
Если же вы не указываете const у аргумента, значит теоретически вы можете перетереть входной аргумент.

и практически тоже:
Код

int foo (int i) {
  int sum=0;
  for (; i != 0; --i)
    sum += i;
  return sum;
}

однако это не касается переменной в вызове, т.к. передается не она сама, а копия, и с точки зрения вызывающего разницы нет.

Это сообщение отредактировал(а) baldina - 8.9.2014, 13:13
PM MAIL   Вверх
Lukkoye
Дата 8.9.2014, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: нет
Всего: 1



Цитата(baldina @  8.9.2014,  13:11 Найти цитируемый пост)
однако это не касается переменной в вызове, т.к. передается не она сама, а копия, и с точки зрения вызывающего разницы нет.


Это действительно не касается вызывающей стороны, несчитая того, 
что теряется информация о том, будет ли вызываемая сторона перетирать данные, или же использовать их только для чтения.

Однако, вызывающая сторона стороне рознь.

Код

int foo (int i) {

    try{
        int sum=0;
        for (; i != 0; --i) //<---- перетираем исходные данные
            Sum(sum,i); //<---- может кинуть исключение
        return sum;
    }
    catch(...)
    {
        //причин для волнений нет, у нас предусмотрена штатная обработка всех возможных проблем
        //просто откатываем весь цикл назад, и восстановливаемся после паники
        ...
             
        //перезапуск функции
        foo(i); //<---- upsss, исходные данные уже безвозвратно запорчены
    }
}


Формально Sum дает строгие гарантии, потому что всегда работает с копией аргумента. 
В случае аварии мы всегда знаем каким было последнее валидное i, с которой операция прошла успешно.

Однако Sum здесь - лишь часть большого цикла. Лишь один из элементов большой транкзации.
В случае провала функции foo, откатить нужно весь цикл, а не только последнюю неудавшуюся итерацию.

Но это не возможно, просто потому, что кому то было лень обезопасить исходные данные:

Код

int foo (const int index) {
    try{
        int sum=0;
        for (int i = index; i != 0; --i)
            Sum(sum,i); 
        return sum;
    }
    catch(...)
    {
        //восстанавливаемся
        ...

        //перезапускаемся      
        foo(index); 
    }
}



Добавлено @ 13:44
Если в каком то частном случае строгие гарантии не нужны, а их обеспечение сопряжено с неоправданными усилиями - тогда конечно не стоит так заморачиваться, и лучше делать так, как проще и удобнее.

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

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




Это сообщение отредактировал(а) Lukkoye - 8.9.2014, 13:45
PM MAIL   Вверх
feodorv
Дата 9.9.2014, 06:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Эх, const это ещё цветочки. Microsoft учудила сначала это, потом это. Вот это да...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0963 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.