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

Работа с const - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 130, средняя оценка - 4.73
adamo86
2 / 2 / 0
Регистрация: 10.04.2011
Сообщений: 185
09.09.2011, 22:17     Работа с const #1
Объясните пожалуйста разницу между вызовами двух функций:

C++
1
int func(const char *name)
и

C++
1
int func(char *name)
Я плохо понимаю - что дает этот спецификатор const? Что может произойти если его не указать?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Zverit
Уничтожитель печенек
 Аватар для Zverit
277 / 205 / 21
Регистрация: 07.02.2010
Сообщений: 723
09.09.2011, 22:21     Работа с const #2
const дает меньше привилегий. И избавляет от случайного изменения данных
adamo86
2 / 2 / 0
Регистрация: 10.04.2011
Сообщений: 185
09.09.2011, 22:25  [ТС]     Работа с const #3
А есть ли смысл тогда писать:

C++
1
int func(const char name)
то есть не указатель, а просто символ? Ведь все равно создается копия переменной.
Zverit
Уничтожитель печенек
 Аватар для Zverit
277 / 205 / 21
Регистрация: 07.02.2010
Сообщений: 723
09.09.2011, 22:39     Работа с const #4
Есть смысл. Если не хотите что бы значение менялось в теле функции, например.
stdcout
53 / 53 / 2
Регистрация: 06.04.2011
Сообщений: 210
09.09.2011, 22:41     Работа с const #5
ITZver, но читающего прототип такой функции отвлечёт спецификатор const к параметру - не указателю. Наверное, никто почти не использует такую форму?
Go0gle
17 / 17 / 1
Регистрация: 08.09.2011
Сообщений: 22
09.09.2011, 23:51     Работа с const #6
Цитата Сообщение от adamo86 Посмотреть сообщение
А есть ли смысл тогда писать:

C++
1
int func(const char name)
то есть не указатель, а просто символ? Ведь все равно создается копия переменной.

Вот Вам маленький примерчик:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include "iostream"
#include "locale"
 
using namespace std ;
 
int getCode(const char name) ;      //Функция возвращает Аски код символа. Принимает константный символ
int getCode1(char  name);           //Функция возвращает Аски код символа. Принимает просто символ
 
int main()
{
    setlocale(LC_ALL,".OCP") ;
 
    const char pStr1 = 'a' ;       //Сивол , который будем передавать в функцию
 
    int nCodeBadge   = getCode(pStr1) ;
    int nCodeBadge1  = getCode1(pStr1) ;
 
    wcout << "Код символа A: " << nCodeBadge <<endl ;  //Получаем значение 97
    wcout << "Код символа A: " << nCodeBadge1<<endl ;  //Получаем значение 98
 
    
    return 0;
}
 
/* Функция принимает константный символ. Это значит, что внутри тела функции парамент name не может ни каким  образом изменить свое значение. Это гарантирует то, что содержимое name не будет изменено. 
*/
int getCode(const char name )
{
    name = 'b' ;    //Ошибка. Не имеем права 
    return (int) name ;
}
 
/* Функция принимает символ. Никакого const нету, поэтому мы может случайно или специально изменить содержимое
  параметра name. 
*/
int getCode1(char name)  //Передаем символ 'a' 
{   
    name = 'b' ;         //Меням содержимое    
    return (int) name;   //Мы передали символ 'a', но получили код символа 'b'
}
Надеюсь Вам помогло.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16935 / 5340 / 328
Регистрация: 30.03.2009
Сообщений: 14,354
Записей в блоге: 26
10.09.2011, 10:55     Работа с const #7
Цитата Сообщение от adamo86 Посмотреть сообщение
А есть ли смысл тогда писать:

C++
1
int func(const char name)
то есть не указатель, а просто символ? Ведь все равно создается копия переменной.
С точки зрения того, кто вызывает функцию - смысла нет, потому как в прототипе модификтор const будет в данном случае игнорироваться, т.к. в прототипе функции учитывается только тип, но не имя переменной. Это легко проверить:

Код
$ cat t.cc
void func (const int x)
{
}

$ g++ t.cc -c
$ readelf --symbols t.o | grep FUNC
     8: 00000000     5 FUNC    GLOBAL DEFAULT    1 _Z4funci
$ c++filt _Z4funci
func(int)
С точки зрения того, кто пишет тело функции, модификатор имеет смысл, чтобы предотвратить собственные ошибки в случае, когда в параметр ничего нельзя записывать. Ведь параметр - это просто локальная переменная функции. Отличие параметра от локальной переменной только в том, что параметр инициализируется снаружи функции и распределяется на регистре или в стеке в соответствии с программными соглашениями, а не так, как того захочет компилятор

C
1
2
3
4
void func (const int x)
{
  x = 0;
}
На таком коде компилятор выругается. Функцию можно писать с const'ами. Но в прототипе const лучше не указывать, потому как с точки зрения вызова функции const не играет никакой роли (потому как в точке вызова создаётся копия фактического параметра), и, как уже говорилось выше, лишняя информация отвлекает. Т.е.

C
1
2
3
4
5
extern void func (int);
...
void func (const int x)
{
}
Можешь ещё почитать здесь Неочевидные ответы на простые вопросы раздел 4
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9383 / 5433 / 916
Регистрация: 25.07.2009
Сообщений: 10,428
10.09.2011, 12:30     Работа с const #8
Думаю, вообще хорошая практика объявлять константным всё, что по логике программы не должно изменяться. Во-первых больше шансов заметить ошибку, во-вторых тонкостей не знаю, но с памятью "только для чтения" работа как-то веселее происходит... Вот, что Отцы-Основатели по этому поводу пишут:
Квалификатор const применяется, разместить объекты в памяти, открытой только на чтение, или чтобы способствовать возможной оптимизации...
Компилятор может игнорировать указанные квалификаторы (const, volatile), однако обязан сигнализировать о явных попытках изменить значение const-объектов.
А 8.2. Спецификаторы типа.
adamo86
2 / 2 / 0
Регистрация: 10.04.2011
Сообщений: 185
10.09.2011, 21:17  [ТС]     Работа с const #9
Тогда поехали дальше... Что дает квалификатор const в данном случае:

C++
1
int func(int i)const {return i+1};
Dani
1263 / 621 / 50
Регистрация: 11.08.2011
Сообщений: 2,236
Записей в блоге: 2
Завершенные тесты: 1
10.09.2011, 21:40     Работа с const #10
это неправда какая-то, ваще не компилируется. Где Вы это взяли?

Добавлено через 12 секунд
Код
1 F:\test\main.cpp non-member function `int func(int)' cannot have `const' method qualifier
Добавлено через 1 минуту
Наверное это отрывок из класса?
C++
1
2
3
4
5
class s 
{
      int func(int i)const {return i+1;}
};
int main(){}
panicwassano
591 / 559 / 20
Регистрация: 07.11.2010
Сообщений: 2,004
10.09.2011, 21:40     Работа с const #11
dani какая неправда? такой код используется в классе, для константных методов
Dani
1263 / 621 / 50
Регистрация: 11.08.2011
Сообщений: 2,236
Записей в блоге: 2
Завершенные тесты: 1
10.09.2011, 21:41     Работа с const #12
Цитата Сообщение от panicwassano Посмотреть сообщение
dani какая неправда? такой код используется в классе, для константных методов
Но тут не было кода класса! А вырывать нельзя. И если гадать, эт неправильно получится.
adamo86
2 / 2 / 0
Регистрация: 10.04.2011
Сообщений: 185
10.09.2011, 21:44  [ТС]     Работа с const #13
Да... Я извиняюсь, это по моему я из класса вырезал, где-то. Что значит константный метод?
Zverit
Уничтожитель печенек
 Аватар для Zverit
277 / 205 / 21
Регистрация: 07.02.2010
Сообщений: 723
10.09.2011, 22:00     Работа с const #14
Цитата Сообщение от adamo86 Посмотреть сообщение
Что значит константный метод?
Метод объекта, который не изменяет данных класса
stdcout
53 / 53 / 2
Регистрация: 06.04.2011
Сообщений: 210
10.09.2011, 22:02     Работа с const #15
adamo86, это значит, что данный метод обязуется не изменять элементы своего класса (он может изменять только элементы со спецификатором const). Имеет смысл использовать для всех методов которые не изменяют состояние объекта. Так же, для константных объектов можно вызывать только константные методы.
adamo86
2 / 2 / 0
Регистрация: 10.04.2011
Сообщений: 185
10.09.2011, 22:02  [ТС]     Работа с const #16
Цитата Сообщение от ITZver Посмотреть сообщение
Метод объекта, который не изменяет данных класса
То есть, к примеру, значения переменных данного объекта, останутся не измененными?
stdcout
53 / 53 / 2
Регистрация: 06.04.2011
Сообщений: 210
10.09.2011, 22:03     Работа с const #17
adamo86, да

Добавлено через 36 секунд
В таких методах могут изменяться только неконстантные элементы объявленные со спецификатором mutable.
adamo86
2 / 2 / 0
Регистрация: 10.04.2011
Сообщений: 185
10.09.2011, 22:06  [ТС]     Работа с const #18
Цитата Сообщение от stdcout Посмотреть сообщение
(он может изменять только элементы со спецификатором const)
Это правильно сказано? Что-то я запутался уже.
stdcout
53 / 53 / 2
Регистрация: 06.04.2011
Сообщений: 210
10.09.2011, 22:13     Работа с const #19
adamo86, блин! прости. опечатался. хотел написать, что может изменять только неконстантный объекты, объявленные со спецификатором mutable.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.09.2011, 00:32     Работа с const
Еще ссылки по теме:

C++ error: invalid operands of types 'const int*' and 'const int*' to binary 'operator+'
C++ Const в параметрах. Перед чем нужно употребить const дабы обезопасить данные от изменения
C++ Чем отличаются выражения (const int[]){value} от (const int[]){100}
C++ Модификатор const для параметра функции не const?
C++ Builder Ошибка E2034: Cannot convert 'char const[8]' to 'const wchar_t *'

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

Или воспользуйтесь поиском по форуму:
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16935 / 5340 / 328
Регистрация: 30.03.2009
Сообщений: 14,354
Записей в блоге: 26
11.09.2011, 00:32     Работа с const #20
Цитата Сообщение от easybudda Посмотреть сообщение
Думаю, вообще хорошая практика объявлять константным всё, что по логике программы не должно изменяться. Во-первых больше шансов заметить ошибку, во-вторых тонкостей не знаю, но с памятью "только для чтения" работа как-то веселее происходит...
Статические переменные (переменные с временем жизни "вся программа") с квалификатором const многие компиляторы складывают в отдельные секции, которые в исполняемом файле попадают сегменты с исполняемым кодом и на уровне операционной системы они попадают в read-only память. Си'шные строковые литералы (текст в кавычках) по сути дела тоже являются const-объектами.

Следующие два кода без проблем пройдут компиляцию. В первом коде имеет место быть явное преобразование указателей и компилятор снимает с себя всю ответственность. Во втором коде работаем со строковым литералом, который по сути есть const-объект, но по языку можно его присваивать в указатель на char без модификатора const, Под линуксом эти коды сломаются на исполнении, под виндой - нет (по крайней мере на борланде у меня не упало)

C
1
2
3
4
5
6
7
8
9
const int a = 5;
 
int main (void)
{
  int *p;
  p = (int*) &a;
  *p = 0;
  return 0;
}
C
1
2
3
4
5
6
int main (void)
{
  char *p = "abcde";
  *p = 0;
  return 0;
}
Yandex
Объявления
11.09.2011, 00:32     Работа с const
Ответ Создать тему
Опции темы

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