Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Модификатор const


Автор: hoz 26.4.2014, 00:27
Читая учебник и попутно размышляя я столкнулся с модификатором const. И по нему у меня вопрос.

Если данный модификатор const используется с переменной то всё понятно. Переменной получено значение один раз, и больше значение данной переменной не изменится в будущем. Но хотя б один раз переменная получит значение. Так?

А как понять метод с модификтором const ?
Ведь в методе то может быть несколько переменных, да и вообще я не совсем понимаю как метод может не изменяться вообще. Есть у кого-нить примеры из практики употребления?

Автор: BlackSpace 26.4.2014, 00:50
hoz, а какую книгу по ООП C++ Вы читаете? 

Автор: feodorv 26.4.2014, 04:07
http://alexandrsoldatkin.com/konstantne-metod/...

Автор: hoz 26.4.2014, 10:11
BlackSpace, Дейтела "Как программировать на С"

Автор: hoz 26.4.2014, 11:36
feodorv, в примере по Вашей ссылке всё расписано очень доходчиво. Но как-бы сказать, у меня всё-таки есть некоторое недопонимание. Попробую объяснить.

Вот данный код:
Код

#include <iostream>
using namespace std;

class Test
{
public:
Test()
{
t = 0;
cnt = 0;
}
void setValue(int val)
{
t = val;       
}
int getValue() const
{      
cnt++;
return t;
}
void debug()
{
cout<<"cnt = "<<cnt<<endl;
}
private:
int t;
mutable int cnt;
};
void main()
{      
Test test;
test.setValue(99);
cout<<test.getValue()<<endl;
test.debug();
}

Данный метод int getValue() const так и так возвращает значение t. Иначе и быть не может. К чему тут модификатор const? Там, в любом случает, нет вероятности изменения переменной t, т.к. метод int getValue() const только возвращает значение t, и, ничего с ней не делает вообще...

Если не вникать в детали и тупо читать, то всё то понятно. Но вот если включить логику, то не совсем понятно. Хочется всё-таки уяснить причину использования данных модификаторов...

Автор: vinter 26.4.2014, 12:26
Цитата(hoz @  26.4.2014,  12:36 Найти цитируемый пост)
Если не вникать в детали и тупо читать, то всё то понятно. Но вот если включить логику, то не совсем понятно. Хочется всё-таки уяснить причину использования данных модификаторов...

ты не можешь использовать неконстантные методы для константных объектов.

Автор: hoz 26.4.2014, 12:34
Цитата(vinter @  26.4.2014,  12:26 Найти цитируемый пост)
ты не можешь использовать неконстантные методы для константных объектов. 

Например?
В выше приведённом примере объект test создан, и он не константный. Через него вызывается как константный метод getValue() const, так и не константный объект void debug().

Автор: vinter 26.4.2014, 12:37
Цитата(hoz @  26.4.2014,  13:34 Найти цитируемый пост)
Например?

Код

void printValue(const Test& test)
{
    std::cout << test.getValue();
}

Автор: hoz 26.4.2014, 12:55
 Тут понятно. Тогда в предыдущем примере, что я привёл выходит, т.к. нет там константного объекта модификатор const был не уместен? Или они на всякий случай так сделали?

Автор: vinter 26.4.2014, 13:21
Цитата(hoz @  26.4.2014,  13:55 Найти цитируемый пост)
Тогда в предыдущем примере, что я привёл выходит, т.к. нет там константного объекта модификатор const был не уместен? Или они на всякий случай так сделали?

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


Автор: hoz 26.4.2014, 13:28
Цитата(vinter @  26.4.2014,  13:21 Найти цитируемый пост)
Поэтому есть золотое правило - все методы должны быть константными, за исключением тех, которые не могут быть ими.

Я сколько встречал примеров константных методов, так попадаются только get-функции. Других не попадалось. Я вот пытаюсь представить какие ещё могут быть примеры употребления модификатора const, но кроме как возвратить некое значение (чаще полученное через get-функцию) ничего на ум не приходит.
Какие ещё бывают варианты употребления модификатора const?

Автор: vinter 26.4.2014, 13:51
operator+,* и т.д. К примеру. 

Автор: hoz 26.4.2014, 14:16
Цитата(vinter @  26.4.2014,  13:51 Найти цитируемый пост)
operator+,* и т.д. К примеру.  

И, опять же, это функция get. Которая больше никаких операций не выполняет...

Автор: vinter 26.4.2014, 14:40
hoz, если что-то не модифицирует внутреннего состояния, то какого поведения ты ожидаешь? Конечно в конечном итоге это всё сводиться к get

Автор: hoz 26.4.2014, 15:01
Цитата(vinter @  26.4.2014,  14:40 Найти цитируемый пост)
hoz, если что-то не модифицирует внутреннего состояния, то какого поведения ты ожидаешь?

vinter, ну я встречал применение данного модификатора для функций print, например. Хотя опять же, подобные операторы лишь выводят на экран (или на какой-нить ещё интерфейс) информацию и всё. Лично мне как-то сложновато понимается тот факт, что функции по факту нечего не изменяют, но тут ещё нужно модификатор поставить, что мол данная функция не изменяет ничего... В том время как и так понятно что они ничего не могут изменить.

Цитата(vinter @  26.4.2014,  14:40 Найти цитируемый пост)
Конечно в конечном итоге это всё сводиться к get 

У Дейтела ещё и принты тоже константные:
Код

printUniversal() const
{
   cout << setfill( '0' ) <<setw( 2 ) << hour << " : " << setw( 2 ) << minite << " : " << setw( 2 ) << second;
}

Автор: BlackSpace 26.4.2014, 15:40
hoz, константный метод не может менять поля класса. Исключение mutable поля класса.
Для чего писать const, если и так метод ничего не меняет? Чтобы другой разработчик ( или сам автор некоторое время спустя ), глядя на объявление метода мог сразу понять, что метод не предназначен для изменения полей класса. 
У Дейтлов метод print() с квалификатором const - так как метод не меняет полей класса.

Автор: Nerevar 28.4.2014, 12:28
hoz,  Квалификатор (модификатор) const в методах задумывался как оберегающий програмиста от самого себя и своих ошибок.

Многие  вам скажут: "константный метод не может менять поля класса" , но забыв при этом добавить, что константный метод может изменять другие переменные не поля класса, а теперь представте, что у вас большой длинный метод ( не какой-нибудь пресловутый "get" ) и вы бьётесь над его написанием несколько суток,  этот метод может возвращать различные значения в зависимости от его внутренних вычислений...и вот вам маленький тривиальненький глупенький примерчик про то как что то может пойти не так:


Код

#include <iostream>
using namespace std;

class Test {
public:

    Test():i(5)    {}

    int change(int a, int b) 
    {
        
        a++;//НЕ поле класса МОЖЕТ ИЗМЕНЯТЬСЯ
        ++b;//НЕ поле класса МОЖЕТ ИЗМЕНЯТЬСЯ
        
        //ТУТ ОПЕЧАТКА вы НЕ проверяете на равенство ВЫ присваиваете i значение а, тем самым
        //Изменяя поле класса, тем самым обрекая проверку if всегда быть верной и всегда возвращать i
        
        if ( i = a )

            return i;

        else

          return b+i;
    }

    int i;
};


int main() {

    int a = 5;
    int b = 5;

    Test T;

    cout << T.change( a, b ) << endl ;

    return 0;
}


Итак как видно из примера из-за, казалось бы, безобидной опечатки метод возвращает не то что нужно да ещё и изменяет поле класа (Элемент даные класса) которым могут пользоваться множество других методов  соответственно зависящих от этой i ...
Тем самым Вы обрекаете себя на многочасовые поиски ошибок в неожиданных местах...И чтобы этого избежать всего то надо изменить метод (элемент-функцию) следующим образом:


 
Код

int change(int a, int b) const
{

}


Здесь вы всё так же сможете изменять a b  и прочие переменные НЕ поля класса, при этом ОБЕРЕГАЯ себя от незапланированных изменений полей класса и в случае:

Код

if ( i = a )

  return i;

Компилятор тут же выбросит вам ошибку в правильном месте явно указав, что конкретно вы делаете не так, а именно что нужно заменить =  на == для проверки равенства i относительно a !


Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/Модификатор-const-id535ad3dbae2015c70d8b4567#findElement_E7045_535e1f45ae201502638ca760_0

Автор: xvr 28.4.2014, 13:01
Цитата(hoz @  26.4.2014,  15:01 Найти цитируемый пост)
Лично мне как-то сложновато понимается тот факт, что функции по факту нечего не изменяют, но тут ещё нужно модификатор поставить, что мол данная функция не изменяет ничего... 

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

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)