Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.69/55: Рейтинг темы: голосов - 55, средняя оценка - 4.69
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,886

Константные и не константные ссылки. Приведения типов. Нужно уточнение

26.11.2015, 23:54. Показов 11235. Ответов 43
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Не очень понимаю в чем различие (2,3 строчки).

C++
1
2
3
 int x = 10;
 double &y = x;
 const double &y = x;
Почему для не константной ссылки временный объект, созданный из x не вяжется с double &,
в то время как временный объект, созданный из x без проблем вяжется с const double &
____________
Просьба не приводить цитаты стандарта, а просто по-человечески описать русскими словами. (русскоязычное описание ситуации при желании можно закрепить стандартом).
Я могу видеть только то, что создается временный объект (const double), который в последствии копируется в y, а т.к. константой инициализировать переменную можно, то для меня логично, что строчка 2 валидна, но это не логично для компиляторов. В то время как строчка 3 валидна и для меня и для компиляторов
1
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
26.11.2015, 23:54
Ответы с готовыми решениями:

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

Можно ли в std::vector хранить константные ссылки?
Можно ли в std::vector хранить константные ссылки? при обьявлении не ругается, когда добавляю (const Item* ) в нем содержится куча...

Константные функции
Почему все работает? class My { public: My(); int retFunc() const; private: bool isRet = false; };

43
265 / 165 / 56
Регистрация: 25.02.2015
Сообщений: 435
27.11.2015, 00:28
Лучший ответ Сообщение было отмечено daslex как решение

Решение

если я правильно помню, то идея была в следующем:
если константная ссылка, то ее менять не будут. значит можно создать временный объект и сослаться на него.
если ссылка неконстантная, то предполагается, что ее будут менять. если при этом создать временный объект, то менять будут его, а его менять нет смысла, т.к. он никому не доступен. поэтому изменение временных объектов запретили. а раз так - такое вот приведение типов сделали ошибкой.
2
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,886
27.11.2015, 00:39  [ТС]
всё понял.
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
27.11.2015, 00:44
А есть другой способ создать константный временный объект?
0
265 / 165 / 56
Регистрация: 25.02.2015
Сообщений: 435
27.11.2015, 00:53
вопрос неясный.
временные объекты вроде не бывают константными в том плане, что они не создаются в какой-то специальной памяти, изменение которой приводит к системной ошибке. они всегда на стеке, в отличие от констант скажем времени компиляции, которые компоновщиком могут быть засунуты в такую память.
0
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,886
27.11.2015, 01:32  [ТС]
Угусь. Конкретика нужна. Ограничили видимость, получили временность. А-то вопрос совсем не грамотно поставлен.
C++
1
2
3
4
5
6
7
8
double x = 100;
 
    {
        const int temp = 100; //temp тоже самое, что константный временный объект.
        x = temp;
    }
// temp умер
// x жив
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6
27.11.2015, 08:47
Цитата Сообщение от Perfilov Посмотреть сообщение
если константная ссылка, то ее менять не будут. значит можно создать временный объект и сослаться на него.
если ссылка неконстантная, то предполагается, что ее будут менять. если при этом создать временный объект, то менять будут его, а его менять нет смысла, т.к. он никому не доступен. поэтому изменение временных объектов запретили. а раз так - такое вот приведение типов сделали ошибкой.
Нет. Это не так. Пример ниже показывает, что на локальную переменную x можно построить как константные так и неконстантные ссылки и спокойно с ними работать. Существенные различия появляются если вы пытаетесь связать возвращаемое значение со ссылкой. В стандарте С++ разрешено связывать временный объект только с константной ссылкой и связанно это только с оптимизацией. Строго говоря при возвращении переменной x из тела функции время ее жизни заканчивается. Т.е. вы не можете модифицировать переменную так как ее фактически уже нет. Однако если вы обещаете не модифицировать переменную то с точки зрения оптимизации нет смысла создавать временную переменную копию x определенную в области видимости вызова функции (в примере это тело функции main()) ,но вместо этого можно продлить время жизни локальной переменной x. Что и происходит.

C++
1
2
3
4
5
6
7
8
9
10
11
double func() {
    double x = 11;
    const double &y = x;
    double &z = x;
    return x;
}
int main(int argc, char *argv[]) {
    const double &y = func();
    double &z = func();
    return 0;
}
Для большей ясности вот пример, показывающий, что временные объекты можно модифицировать.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
class foo {
int i;
public:
    foo(int t) : i(t)
    {}
    void increment() {
        std::cout << ++i << std::endl;
    }
};
int main(int argc, char *argv[]) {
    {
        foo(11).increment();
    }
    return 0;
}
0
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,886
27.11.2015, 10:16  [ТС]
Ilot, А я вижу только создание локальной копии, которая и сама по себе не константа и не та константа, которая передается в объект. Т.е. увеличение локальной копии обыкновенной не константной переменной, которая к константам никакого отношения не имеет.
передача по значению. (в примере для ясности)

Добавлено через 6 минут
А первый пример компиляторы, уважающие стандарт, не съедят.
только const
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6
27.11.2015, 10:23
Цитата Сообщение от daslex Посмотреть сообщение
А первый пример компиляторы, уважающие стандарт, не съедят.
только const
Правильно. Вы комментарий перед программой читали?

Цитата Сообщение от daslex Посмотреть сообщение
Ilot, А я вижу только создание локальной копии, которая и сама по себе не константа и не та константа, которая передается в объект. Т.е. увеличение локальной копии обыкновенной не константной переменной, которая к константам никакого отношения не имеет.
передача по значению. (в примере для ясности)
Это ответ на:
Цитата Сообщение от Perfilov Посмотреть сообщение
поэтому изменение временных объектов запретили. а раз так - такое вот приведение типов сделали ошибкой.
Я привел пример того, что это не так - временные объекты можно изменять.

А почему подобное приведение типов запрещено указано в первой части поста.
Вы же стпросили:
Цитата Сообщение от daslex Посмотреть сообщение
Почему для не константной ссылки временный объект, созданный из x не вяжется с double &,
в то время как временный объект, созданный из x без проблем вяжется с const double &
Где здесь указано, что временный объект константный?
0
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,886
27.11.2015, 10:34  [ТС]
Там они в памяти создаются и нам недоступны ни для просмотра, ни для изменения. Логично, что их создание должно обозначаться квалификатором const.
Тут вроде как каша намечается, а каша не нужна. Изначально я об этих невидимых взору объектах спросил, на что мне и отвечено именно в том виде, который Вы далее уточняете.
Изначально речи об объектах, создаваемых нами и видимым нам, не шло.
Тут начинается отклонение. Вы, конечно, правильно пишете. Просто акценты смещаются.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
27.11.2015, 13:59
daslex, на самом деле ответ на этот вопрос дал сам Страуструп в своей книге "Дизайн и эволюция С++" и этот ответ прост и не требует замысловатых рассуждений.
Вот здесь я объяснил причины на примере. Подробности в книге "Дизайн и Эволюция C++", глава 3.9 - Ссылки.
4
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,886
27.11.2015, 18:18  [ТС]
Нужно еще одно уточнение в чем-то похожей, но другой ситуации.

C++
1
2
3
4
5
6
7
8
9
10
void foo(const int Arr[], const int &N,  const int COL=0) {  //Аргумент по умолчанию для убедительности
    int arr[COL];
}
 
int main()
{
    const int N = 100;
    int arr[N];
    foo(arr, N, 30);
}
Я всегда думал, что это тоже самое, что и
C++
1
2
3
4
5
6
7
8
9
10
11
void foo(const int Arr[], const int &N) {
    const int COL = 30;  
    int arr[COL];
}
 
int main()
{
    const int N = 100;
    int arr[N];
    foo(arr, N);
}
Но компилятор говорит, что COL в первом листинге не константа. Я его вообще не понимаю.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
27.11.2015, 19:06
Цитата Сообщение от daslex Посмотреть сообщение
Но компилятор говорит, что COL в первом листинге не константа. Я его вообще не понимаю.
Размерность массива должна быть задана константой времени компиляции. Т.е. значение константы должно быть однозначно выводимо на этапе компиляции.
Аргумент функции здесь константа только логически (на уровне системы типов). Но конкретное значение аргумента функции (внутри функции) становится известным уже во время исполнения. О чем, собственно, компилятор тебе и пытается сказать.
1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,886
28.11.2015, 00:53  [ТС]
Но тогда это не должно компилироваться. Не похоже, что размерность массива задается во время компиляции, а похоже, что она становится известна во время исполнения (выбор-то делается во время исполнения)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
    int x;
    std::cin >> x;
    if (x) {
        const int N = 5;
        int arr[N] = { 1,2,3,4,5 };
        for (const auto &i : arr) std::cout << i << ' ';
    }
    else {
        const int N = 6;
        int arr[N] = { 5,6,7,8,9,0 };
        for (const auto &i : arr) std::cout << i << ' ';
    }
}
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
28.11.2015, 04:36
Цитата Сообщение от daslex Посмотреть сообщение
Но тогда это не должно компилироваться.
А подумать?

Цитата Сообщение от daslex Посмотреть сообщение
C++
1
const int N = 5;
Это как раз таки и есть константа времени компиляции, до тех пор пока по каким-то причинам не понадобится разместить ее в памяти. В этом коде таких причин нет, поэтому он компилируется.

Цитата Сообщение от daslex Посмотреть сообщение
Не похоже, что размерность массива задается во время компиляции, а похоже, что она становится известна во время исполнения (выбор-то делается во время исполнения)
Выбор между определенными на этапе компиляции участками кода. Это же очевидно. Для каждого участка - своя константа.

А вообще ну открой уже стандарт. Там же написано очень четко: размерность массива - константа времени компиляции.
Твой пример с функцией - другое. Там задействуется механизм передачи параметров (через стек или регистры - не суть), который сам по себе уже runtime.
1
1130 / 789 / 232
Регистрация: 12.04.2010
Сообщений: 2,012
28.11.2015, 18:45
Цитата Сообщение от daslex Посмотреть сообщение
double &y = x;
Такая запись означает, что x и y - разные имена одного и того же объкта. Поэтому x и y должны быть одного типа.

Добавлено через 8 минут
Цитата Сообщение от daslex Посмотреть сообщение
void foo(const int Arr[], const int &N, const int COL=0)
Цитата Сообщение от daslex Посмотреть сообщение
компилятор говорит, что COL в первом листинге не константа
Потому что можно будет написать в программе
C++
1
2
3
f( p, n, 10 ); 
f( p, n, 20 ); 
f( p, n, 30 );
Добавлено через 6 минут
Цитата Сообщение от Perfilov Посмотреть сообщение
поэтому изменение временных объектов запретили
Perfilov, а каком запрете Вы говорите?
C++
1
2
3
4
5
long a = 1;
long & b = a;
++a;
++b; 
// cout << ...
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
28.11.2015, 18:50
Цитата Сообщение от Alex5 Посмотреть сообщение
а каком запрете Вы говорите?
и где ваш код меняет значение временного объекта??? Объект "a" будет жить вне одной операции, и тем более ссылка на этот объект.
0
1130 / 789 / 232
Регистрация: 12.04.2010
Сообщений: 2,012
28.11.2015, 19:41
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
где ваш код меняет
Код меняет значения a, b. rikimaru2013, а что Вы здесь

Цитата Сообщение от Alex5 Посмотреть сообщение
long a = 1;
long & b = a;
++a;
++b;
называете "временным объектом" ? (msdn - временные объекты)
0
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,886
28.11.2015, 19:47  [ТС]
Предотвращая некоторые не очень желательные продолжения поясню.
Все ответы, на заданные мною в этой теме вопросы, выше я уже получил.

Цитата Сообщение от Alex5 Посмотреть сообщение
Такая запись означает, что x и y - разные имена одного и того же объкта. Поэтому x и y должны быть одного типа.
угу, а продолжим цепочку:
C++
1
2
3
4
5
const double &y = x; //  x и y должны быть одного типа., 
                     //  компилируется, значит они одного типа,
                     //  const double - Это тип int
                     //     (я - гений).
                     //   *злобный смех*
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
28.11.2015, 19:54
Alex5,
если вы думаете, что в вашем коде
C++
1
2
3
4
long a = 1;
long & b = a;
++a;
++b;
строки ++a и ++b меняют временные объекты компилятора изменение которых запрещены, то мне будет очень тяжело вам, что-то доказать в дальнейшем и я сдаюсь прям сейчас (
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
28.11.2015, 19:54
Помогаю со студенческими работами здесь

Константные объекты
#include &lt;iostream&gt; #include &lt;windows.h&gt; using namespace std; class CTest { public: int A,B; CTest(int Aval,int...

Указатели на константные объекты
Нельзя создать неконстантный указатель на константный объект по понятным причинам, но имеем такой код: typedef char* pStr; int...

Константные поля класса
Такой вопрос, как инициализировать константные поля класса? Работают конструкции вида obj():t(0){}; который используется в примере ниже. А...

Константные функции-члены
можно ли функцию-член объявить константной, если она возвращает указатель-член класса? Ведь она не изменяет занчение самого укзателя, но...

Константные аргументы классов
Добрый вечер! Поясните мне в чем беда.. есть код: // Hanoian towers. Lab2 #include &lt;iostream&gt; using namespace std; ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru