Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
45 / 0 / 0
Регистрация: 10.04.2016
Сообщений: 114
1

Работа с ключевым словом const

20.02.2019, 11:43. Просмотров 1269. Ответов 21

Всем мира!
Снова приходится обращаться к вам, дорогие форумчане за разъяснением вот какой штуки. Сейчас изучаю Эффективное Использование С++ Скотта Майерса и возник такой вопрос, на который я не могу найти ответ ни на просторах интернета, ни в книге. Подразумевается что я должен это знать и понимать и это очевидные вещи, но таких конструкций ранее не встречал.
К делу:

C++
1
int massiv::get_size() const
C++
1
const int massiv::get_size()
Выше приведенные выражения по смыслу тождественны?

И второй вопрос. Вот есть у нас перегруженные операторы

C++
1
2
3
4
5
const massiv &operator=(const massiv &ob);
massiv &operator+=(const massiv &ob);
bool operator==(const massiv &ob) const;
int& operator[](int);
massiv operator+(const massiv ob1);
По какому принципу где-то пишется const, где-то передаем объект по ссылке, где-то по значению, где-то возвращаем ссылку (константную или нет), а где то значение. Где то const пишется перед типом (1ый случай), а где-то после всего прототипа перегруженного оператора (3ий случай).

Объясните, пожалуйста, как это работает. Я понимаю, что это вообще ключевые моменты, и облегчат мне жизнь, и защитят мои данные. Необходимо понимание...
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.02.2019, 11:43
Ответы с готовыми решениями:

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

Различие между оператором new и ключевым словом new
Решая эту задачу https://stepik.org/lesson/563/step/7?unit=886 набрёл на статью которая меня очень...

Шифрование/дешифрование шифра Трисемуса с любым ключевым словом
Помогите,пожалуйста написать программу по шифровке и дешифровке шифра Трисемус с любым ключевым...

Как зашифровать текст из файла шифрованием Цезаря с ключевым словом?
в общем дан текст в файле.Нужно зашифровать его, например, с помощью кода Ascii, и записать в...

21
Mental handicap
1241 / 619 / 171
Регистрация: 24.11.2015
Сообщений: 2,426
20.02.2019, 11:50 2
Цитата Сообщение от Руслан92 Посмотреть сообщение
Выше приведенные выражения по смыслу тождественны?
Нет, const (или же в общем случае cv-qualifier) в конце метода относится к this и вне класса это не работает.
Цитата Сообщение от Руслан92 Посмотреть сообщение
Объясните, пожалуйста, как это работает.
const - накладывает на объект иммутабельность, вот и все, используем где надо, только не путать с иммутабельными объектами из других языков, поддержки которых нету в С++.
1
13471 / 7134 / 1712
Регистрация: 30.01.2014
Сообщений: 11,919
20.02.2019, 11:52 3
Цитата Сообщение от Руслан92 Посмотреть сообщение
приведенные выражения по смыслу тождественны?
Нет.

Цитата Сообщение от Руслан92 Посмотреть сообщение
bool operator==(const massiv &ob) const;
Если вы напишете этот оператор как свободную функцию
C++
1
bool operator==(const massiv &ob1, const massiv &ob2);
то const после функции в случае метода по смыслу тот же const у первого параметра ob1.
Т.е., коротко говоря, const после функции относится к this.
1
Mental handicap
1241 / 619 / 171
Регистрация: 24.11.2015
Сообщений: 2,426
20.02.2019, 11:53 4
Цитата Сообщение от Руслан92 Посмотреть сообщение
Я понимаю, что это вообще ключевые моменты, и облегчат мне жизнь, и защитят мои данные. Необходимо понимание.
Цитата Сообщение от Руслан92 Посмотреть сообщение
Сейчас изучаю Эффективное Использование С++ Скотта Майерса
Видимо рановато перешли.
1
45 / 0 / 0
Регистрация: 10.04.2016
Сообщений: 114
20.02.2019, 12:01  [ТС] 5
DrOffset,
C++
1
massiv operator+(const massiv ob1);
Почему здесь объект передается по значению?

З.Ы. т.е. я правильно понимаю, что const после прототипа относится к вызывающему оператор объекту, а const перед типом переменной в самом начале прототипа функции (оператора) - возвращаемое значение становится const (или принимается к возврату только const)?

Почему в случае перегрузки (=) возвращаем const, а в случае (+=) не const?
0
734 / 339 / 70
Регистрация: 10.06.2014
Сообщений: 2,356
20.02.2019, 12:09 6
Руслан92,
Вообще const хоть и выглядит просто но вокруг этого дела крутится много всего.
Например в некоторых случаях компилятор "может использовать" эту информацию для оптимизации
C++
1
2
3
const int n = 1;
//...
std::cout << n; // скорее всего значение 1 будет подставлено напрямую т.к n это константа  и не имеет других значений
Или например у вас есть функция которая принимает константную ссылку на экземпляр класса
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct container
{
    size_t size() const
    {
        return 0;
    }
};
 
void f(const container &c)
{
    std::cout << c.size();
}
 
int main()
{
    f(container());
}
если метод size не объявить как const, то работать не будет т.к мы пытаемся вызвать неконстантный метод у константной ссылки (это может привести к изменению передаваемого объекта но мы ведь сказали что ссылка ничего менять не будет).
к тому же в данном примере при вызове f передается ссылка на временный объект.
если бы ссылка не была константной, то код так же не скомпилировался бы

Потом например можно делать перегрузку методов по const
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
 
struct foo
{
    void method()
    {
        std::cout << "For non const object\n";
    }
    void method() const
    {
        std::cout << "For const object\n";
    }
};
 
int main()
{
    foo f1;
    const foo f2;
    f1.method();
    f2.method();
}
А при возвращаемых значениях const обычно используется для возврата указателя или ссылки когда мы не хотим что бы на вызывающей стороне была возможность менять возвращаемые данные.

Добавлено через 7 секунд
Руслан92,
Вообще const хоть и выглядит просто но вокруг этого дела крутится много всего.
Например в некоторых случаях компилятор "может использовать" эту информацию для оптимизации
C++
1
2
3
const int n = 1;
//...
std::cout << n; // скорее всего значение 1 будет подставлено напрямую т.к n это константа  и не имеет других значений
Или например у вас есть функция которая принимает константную ссылку на экземпляр класса
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct container
{
    size_t size() const
    {
        return 0;
    }
};
 
void f(const container &c)
{
    std::cout << c.size();
}
 
int main()
{
    f(container());
}
если метод size не объявить как const, то работать не будет т.к мы пытаемся вызвать неконстантный метод у константной ссылки (это может привести к изменению передаваемого объекта но мы ведь сказали что ссылка ничего менять не будет).
к тому же в данном примере при вызове f передается ссылка на временный объект.
если бы ссылка не была константной, то код так же не скомпилировался бы

Потом например можно делать перегрузку методов по const
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
 
struct foo
{
    void method()
    {
        std::cout << "For non const object\n";
    }
    void method() const
    {
        std::cout << "For const object\n";
    }
};
 
int main()
{
    foo f1;
    const foo f2;
    f1.method();
    f2.method();
}
А при возвращаемых значениях const обычно используется для возврата указателя или ссылки когда мы не хотим что бы на вызывающей стороне была возможность менять возвращаемые данные.
1
45 / 0 / 0
Регистрация: 10.04.2016
Сообщений: 114
20.02.2019, 12:09  [ТС] 7
Видимо рановато перешли.
Да не рановато. Без таких вот затыков, как понять насколько ты знаешь и владеешь языком. А так нарвался, наткнулся, выяснил и жить становится лучше
0
Mental handicap
1241 / 619 / 171
Регистрация: 24.11.2015
Сообщений: 2,426
20.02.2019, 12:15 8
Цитата Сообщение от Руслан92 Посмотреть сообщение
возвращаемое значение становится const
На возвращаемый объект накладывается иммутабельность.
Цитата Сообщение от Руслан92 Посмотреть сообщение
Почему в случае перегрузки (=) возвращаем const, а в случае (+=) не const?
Все по тем же причинам, можете убрать const всеравно будет работать.
1
45 / 0 / 0
Регистрация: 10.04.2016
Сообщений: 114
20.02.2019, 12:18  [ТС] 9

Undisputed
, в общих чертах понятно.
Непонятно вот что.

C++
1
massiv &operator+=(const massiv &ob);
При передаче объекта по ссылке обычно предполагается, что он в принимающей функции будет меняться (иначе зачем передавать вообще по ссылке? можно и по значению тогда передать. Стек заполнится немного, но кроме этого по смыслу ничего не изменится). Вопрос такой тогда: как передача объекта (или чего-либо по ссылке) работает со словом const? Const говорит, что ничего менять нельзя, ссылка говорит, что менять можно. Параллакс.
0
13471 / 7134 / 1712
Регистрация: 30.01.2014
Сообщений: 11,919
20.02.2019, 12:23 10
Цитата Сообщение от Руслан92 Посмотреть сообщение
Почему здесь объект передается по значению?
У автора надо спросить. Я бы (в параметре) не передавал.

Цитата Сообщение от Руслан92 Посмотреть сообщение
Почему в случае перегрузки (=) возвращаем const, а в случае (+=) не const?
Опять же, надо спросить у автора. Видимо он не хотел, чтобы результат выражения присваивания можно было модифицировать.
Обычно это не требуется.

Добавлено через 2 минуты
Цитата Сообщение от Руслан92 Посмотреть сообщение
Const говорит, что ничего менять нельзя, ссылка говорит, что менять можно.
Ссылка не говорит сама по себе ничего такого
Ссылка нам говорит, что это псевдоним объекта. А можно или нельзя через него объект менять - это уже зависит от const-квалификации.
1
45 / 0 / 0
Регистрация: 10.04.2016
Сообщений: 114
20.02.2019, 12:23  [ТС] 11
возвращаемое значение становится const (или принимается к возврату только const)?

C++
1
const int& (int a);
0
734 / 339 / 70
Регистрация: 10.06.2014
Сообщений: 2,356
20.02.2019, 12:24 12
Цитата Сообщение от Руслан92 Посмотреть сообщение
При передаче объекта по ссылке обычно предполагается, что он в принимающей функции будет меняться
Нет. Если так предполагается то передавать константную ссылку нежелательно
Цитата Сообщение от Руслан92 Посмотреть сообщение
иначе зачем передавать вообще по ссылке?
как минимум для того что бы избежать лишнее копирование объекта
Цитата Сообщение от Руслан92 Посмотреть сообщение
и по значению тогда передать.
будет копирование. с точки зрения производительности не есть хорошо

+= обычно изменяет левый операнд
C++
1
2
3
int a = 1;
const int b = 2;
a += b; // меняется левый операнд а правый нет
Цитата Сообщение от Руслан92 Посмотреть сообщение
Вопрос такой тогда: как передача объекта (или чего-либо по ссылке) работает со словом const? Const говорит, что ничего менять нельзя, ссылка говорит, что менять можно.
const говорит что менять нельзя а ссылка говорит что мы ссылаемся на переданный объект
можно ссылаться не объект не меняя его
более того, без дополнительных трюков изменить значение константной ссылки не выйдет.
1
45 / 0 / 0
Регистрация: 10.04.2016
Сообщений: 114
20.02.2019, 12:30  [ТС] 13
DrOffset
Цитата Сообщение от DrOffset Посмотреть сообщение
Ссылка не говорит сама по себе ничего такого
Ссылка нам говорит, что это псевдоним объекта. А можно или нельзя через него объект менять - это уже зависит от const-квалификации.
Зачем вообще тогда передавать по ссылке со словом const? Только из-за экономии стека?

Добавлено через 5 минут
Undisputed, DrOffset
т.е. предпочтительно всегда что-то передавать по ссылке? Просто если хочешь, чтоб после передачи в качестве аргумента объект (или что-либо) не изменился нужно предварить его словом const. Если предполагается его изменение тогда const не пишем. Но и в том, и в другом случае передаем по ссылке?

Зачем вообще тогда нужна передача по значению?
0
13471 / 7134 / 1712
Регистрация: 30.01.2014
Сообщений: 11,919
20.02.2019, 12:33 14
Цитата Сообщение от Руслан92 Посмотреть сообщение
Зачем вообще тогда передавать по ссылке со словом const? Только из-за экономии стека?
По моему вы недооцениваете серьезность вопроса.
Стек в общем-то тут не главное. Конструктор копирования может реализовывать серьезную логику, которую нежелательно задействвовать на каждый чих. Естественно, в частных случаях у нас есть выбор, и иногда он наоборот склоняется в сторону копирования. Но вы должны понимать предпосылки к этому (например, одиночный int наоборот лучше передать по значению). Если же вы собрались копировать тяжеловесный класс, например, реализующий базу данных, то это может иметь серьезные последствия для производительности - следовательно выбор в сторону копирования может быть осуществлен только если это вам действительно нужно.

Добавлено через 2 минуты
Цитата Сообщение от Руслан92 Посмотреть сообщение
т.е. предпочтительно всегда что-то передавать по ссылке?
Вот вы водите машину? Попробовали бы вы у инструктора, когда учились, спросить "т.е. предпочтительно всегда поворачивать направо?"
Как думаете, что бы он вам на это ответил?
3
45 / 0 / 0
Регистрация: 10.04.2016
Сообщений: 114
20.02.2019, 12:35  [ТС] 15
Цитата Сообщение от DrOffset Посмотреть сообщение
например, одиночный int наоборот лучше передать по значению
Почему?

Добавлено через 1 минуту
Цитата Сообщение от DrOffset Посмотреть сообщение
Вот вы водите машину? Попробовали бы вы у инструктора, когда учились, спросить "т.е. предпочтительно всегда поворачивать направо?"
Как думаете, что бы он вам на это ответил?
Как минимум, попросил бы выйти из машины и больше не приближаться к ней

В чем преимущества передачи по значению перед передачей по ссылке со словом const?

Добавлено через 14 секунд
Цитата Сообщение от DrOffset Посмотреть сообщение
Вот вы водите машину? Попробовали бы вы у инструктора, когда учились, спросить "т.е. предпочтительно всегда поворачивать направо?"
Как думаете, что бы он вам на это ответил?
Как минимум, попросил бы выйти из машины и больше не приближаться к ней

В чем преимущества передачи по значению перед передачей по ссылке со словом const?
0
13471 / 7134 / 1712
Регистрация: 30.01.2014
Сообщений: 11,919
20.02.2019, 12:38 16
Цитата Сообщение от Руслан92 Посмотреть сообщение
Почему?
Потому что если вы не собираетесь его менять, то преимуществ в варианте с константной ссылкой нет. Т.к. размер int обычно меньше или равен размеру указателя, через который ссылка реализуется в этих случаях. А копирование и того и другого как правило эквивалентно с точки зрения производительности.

Добавлено через 2 минуты
Цитата Сообщение от Руслан92 Посмотреть сообщение
В чем преимущества передачи по значению перед передачей по ссылке со словом const?
Если вам нужно копирование - вы используете копирование, если не нужно копирование и при этом не собираетесь менять аргумент - передавайте ссылку на const. Если собираетесь менять - передавайте ссылку.
1
Mental handicap
1241 / 619 / 171
Регистрация: 24.11.2015
Сообщений: 2,426
20.02.2019, 12:47 17
Цитата Сообщение от Руслан92 Посмотреть сообщение
В чем преимущества передачи по значению перед передачей по ссылке со словом const?
Вам же уже дали ответ, причем раза 2-3.

Иногда вообще преимущества может не быть, даже не для базовых типов.
Компилятор засунет объект целиком в регистр и преимущества не будет.
https://godbolt.org/z/vLEYrI
1
734 / 339 / 70
Регистрация: 10.06.2014
Сообщений: 2,356
20.02.2019, 12:50 18
Руслан92,
Если вы не видите причин для копий - лучше используйте ссылки.
Зачем переплачивать если в этом нет необходимости?
Кроме того что лишнее копирование может ухудшить производительность это так же может нарушить логику программы
Допустим нам надо считать количество активных экземпляров класса
Ок, добавим счетчик
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
41
42
43
44
45
#include <iostream>
 
class Foo
{
public:
    Foo()
    {
        ++count_;
    }
    
    Foo(const Foo &source)
    {
        data_ = source.data_;
        ++count_;
    }
    
    size_t count() const
    {
        return count_;
    }
    
    ~Foo()
    {
        --count_;
    }
    
private:
    static size_t count_;
    int data_;
};
 
size_t Foo::count_ = 0;
 
void func(Foo f)
{
    std::cout << f.count(); // 2 ??? мы же один объект создали
}
 
int main()
{
   Foo f;
   std::cout << f.count() << '\n';
   func(f);
   
}
Как видите получили не то что ожидали.
1
45 / 0 / 0
Регистрация: 10.04.2016
Сообщений: 114
20.02.2019, 12:57  [ТС] 19
Спасибо большое всем!! Вроде понял! Даже легче стало! Теперь надо поэкспериментировать.

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

Спасибо!

Добавлено через 4 минуты
Как видите получили не то что ожидали.
Это получилось потому что вот здесь
C++
1
2
3
4
void func(Foo f)
{
    std::cout << f.count(); // 2 ??? мы же один объект создали
}
надо было написать
C++
1
2
3
4
void func(Foo &f)
{
    std::cout << f.count(); // 2 ??? мы же один объект создали
}
т.е. передать по ссылке объект?
0
734 / 339 / 70
Регистрация: 10.06.2014
Сообщений: 2,356
20.02.2019, 13:03 20
Лучший ответ Сообщение было отмечено Руслан92 как решение

Решение

Руслан92,
Да. Опять же, может быть так что понадобится копия
Надо просто понимать что и как работает и применять фичи где они подходят

Добавлено через 24 секунды
Всему своё место
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.02.2019, 13:03

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Скажите, почему нельзя полностью отказаться от char, при этом сделав string стандартным ключевым словом языка?
Скажите,почему нельзя полностью отказаться от char,при этом сделав string стандартным ключевым...

Поиск по ключевым словом
Плиз помогите я делаю справочник по С++ все сделал, но вот проблема с поиском код есть и выводит он...

Цезарь с ключевым словом
Всем привет. Может у кого есть реализация в Delphi это алгоритма или кто может написать за плату?

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

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