Russian Qt Forum
Март 29, 2024, 18:52 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: const до/после *  (Прочитано 14380 раз)
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 862


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #15 : Октябрь 10, 2019, 11:49 »

Код:
const int *
Слева никого нету. И шо Непонимающий
Тогда зацикливаем выражение, типа переносим вправо ))
Код:
int * var const
указатель на константу типа int.
Страуструп говорил, что лишь "некоторые люди находят удобным читать такие объявления справа налево. Еще он утверждал, что "никакого декларатора const* не существует" (в кавычках - цитаты). Очень многие правила - с исключениями))
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #16 : Октябрь 10, 2019, 17:36 »

Слева никого нету. И шо Непонимающий

модификаторы типа T могут стоять как справа, так и слева от Т:
int volatile const a;
и рассматриваются как единое целое

Под T подразумевается корректный идентификатор (т.е. некое имя типа без звездочек скобочек и прочего).
Всё остальное читается справа налево (звездочки, ссылки, скобочки).
Видим звездочку - говорим "указатель на" и читаем дальше. Видим T, читаем вперед пока не дойдем до конца или не встретим следующий "разделитель" (звездочку, например).
Вас же не удивляет наличие оператора ++ как же так, два плюса подряд, ведь после плюса должно выражение быть. А еще можно написать 5 + +10 вообще кошмар.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #17 : Октябрь 11, 2019, 09:31 »

модификаторы типа T могут стоять как справа, так и слева от Т:
int volatile const a;
и рассматриваются как единое целое
Существенно, спасибо

Но мы несколько зациклились на избитых примерах. А ну чуть копнем
Код
C++ (Qt)
void Test( const int ** a )
{
 a = 0;   // ok
 *a = 0;  // ok
//  **a = 0;  // error
}
Часто это и нужно, напр есть массив неперемещаемых данных, нужно сортировать его так и сяк, потом работать с сортированным. Ну делаем массив указателей, сортируем его и обрабатываем ф-цией Test выше. Однако

Код
C++ (Qt)
int data = 5;
std::vector<int *> vecPtr;
vecPtr.push_back(&data);
Test(&vecPtr[0]);      // error
const int ** test = &vec[0]; // error
И никак  Плачущий ("пока не купите стиральную машину "Вятка"), т.е. пока не изменить тип вектора на const int *. Что не очень удобно - это я в Test хочу константные данные - а напр в Test2 могу и менять

ЧЯДНТ?
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #18 : Октябрь 11, 2019, 13:06 »

ЧЯДНТ?

Много чего. Например, не читаете документацию, не предоставляете удобные примеры кода, которые можно быстро исправить и проверить работоспособность.

Это же очень трудно, оформить пример в таком виде:
Код
C++ (Qt)
#include <vector>
#include <iostream>
 
using namespace std;
 
void test(int** p)
{
   cout << "mutable int = " << **p << endl;
}
 
void test(int const* const* p)
{
   cout << "const   int = " << **p << endl;
}
 
int main()
{
   int data = 5;
   vector<int*> vecPtr;
   vecPtr.push_back(&data);
 
   test(&vecPtr[0]);
   test(static_cast<int const* const*>(&vecPtr[0]));
 
   return 0;
}
Записан

Пока сам не сделаешь...
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #19 : Октябрь 12, 2019, 09:28 »

Код
C++ (Qt)
   test(static_cast<int const* const*>(&vecPtr[0]));
}
Это "лучше чем ничего", но полноценным не является, константные указатели никто не заказывал. Интересно что
Код
C++ (Qt)
test(const_cast<const int **>(&vecPtr[0]));
Проходит. Оказывается const_cast умеет не только "снимать" константность Улыбающийся При упоминании о const_cast немедленно сыпятся упреки "корявая архитектура" (хотя архитектура-то здесь причем?), "костыль" и.т.п. Ну а здесь чем он плох? Что может сломаться (при любых "если"). Не вижу
 
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #20 : Октябрь 12, 2019, 10:52 »

Это "лучше чем ничего", но полноценным не является, константные указатели никто не заказывал.

А Вы собираетесь в функции, которая работает с const int, менять указатели? И там именно одиночный int, а не что-то другое?

Интересно что
Код
C++ (Qt)
test(const_cast<const int **>(&vecPtr[0]));
Проходит. Оказывается const_cast умеет не только "снимать" константность Улыбающийся При упоминании о const_cast немедленно сыпятся упреки "корявая архитектура" (хотя архитектура-то здесь причем?), "костыль" и.т.п. Ну а здесь чем он плох? Что может сломаться (при любых "если"). Не вижу

Вы же до конца дочитали Const Correctness FAQ по ссылке, что я давал? Если Вы не видите, что что-то может сломаться, значит оно не сломается. Не слушайте всяких теоретиков, компиляторщиков, пишите const_cast'ов побольше, Вы же лучше знаете Улыбающийся.
Записан

Пока сам не сделаешь...
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #21 : Октябрь 12, 2019, 15:29 »

Цитировать
Вы же до конца дочитали Const Correctness FAQ по ссылке, что я давал? Если Вы не видите, что что-то может сломаться, значит оно не сломается. Не слушайте всяких теоретиков, компиляторщиков, пишите const_cast'ов побольше, Вы же лучше знаете  Улыбающийся
Мне думается, что у Igorsа проблема гораздо глубже лежит  Улыбающийся
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #22 : Октябрь 12, 2019, 16:39 »

А Вы собираетесь в функции, которая работает с const int, менять указатели? И там именно одиночный int, а не что-то другое?
Почему нет? Ну хотя бы эти указатели нужно сортировать

Вы же до конца дочитали Const Correctness FAQ по ссылке, что я давал? Если Вы не видите, что что-то может сломаться, значит оно не сломается. Не слушайте всяких теоретиков, компиляторщиков, пишите const_cast'ов побольше, Вы же лучше знаете Улыбающийся.
Не стоит раздражаться. Да, const_cast не есть хорошо, и, прежде чем его писать, надо еще раз подумать как обойтись без него. Но если, как в данном случае, лучшего не видно - ну значит const_cast, на всякое правило есть исключение. Кстати и в исходниках Qt они совсем не "музейная редкость"
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #23 : Октябрь 12, 2019, 21:46 »

Я просто не понимаю, чем обусловлено использование таких конструкций
Код
C++ (Qt)
int data = 5;
std::vector<int *> vecPtr;
vecPtr.push_back(&data);
Test(&vecPtr[0]);      // error
const int ** test = &vec[0]; // error
 
в современном c++  Улыбающийся
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #24 : Октябрь 13, 2019, 02:52 »

Код
C++ (Qt)
// оказывается такая запись
typedef int * PInt;
const PInt a;
 
// равнозначна такой (константный указатель)
int * const a;
 
// а вовсе не такой (указатель на константу)
const int * a;
Чего это?

const T - T является константой.
если T - указатель, значит указатель и является константой
незменяемый указатель имеет вид: type* const

как вообще это можно было неправильно понять?
Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #25 : Октябрь 13, 2019, 02:55 »

Видимо, для удобства кожаных ублюдков (которые читают слева направо) было сделано исключение (ну а чо, удобно же).

кто такие "кожанные ублюдки" ?

Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #26 : Октябрь 13, 2019, 09:51 »

Я просто не понимаю, чем обусловлено использование таких конструкций
...
в современном c++  Улыбающийся

У меня есть версия, что там не современный С++, а старый Си с классами, хоть и в новой обёртке Улыбающийся.
Записан

Пока сам не сделаешь...
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #27 : Октябрь 13, 2019, 15:55 »


кто такие "кожанные ублюдки" ?



https://www.youtube.com/watch?v=4TpeG-nQhJ4
Записан
AkonResumed
Чайник
*
Offline Offline

Сообщений: 81


Просмотр профиля
« Ответ #28 : Апрель 20, 2021, 07:35 »

Как насчет следующей формализации при объявлении переменных сложных типов:

1. Тип просто определяет размер области памяти (он, конечно, определяет много чего еще, но нам здесь это неважно). Более никаких атрибутов тип не имеет, т.е. const - это не про тип. Когда объявляется переменная типа, то мы получаем конкретный кусок памяти, характеризуемый размером и адресом. И вот тут уместно определить атрибут доступа к этому конкретному куску - если только чтение, то const. Т.е. const - это атрибут конкретного адреса памяти, а не типа.

2. const пишется всегда слева и воздействует на то, что справа. 'const T' - запрещено, т.к. из п.1 мы определели, что "const - это не про тип".

3. Будем считать косвенный доступ '*' (т.е. доступ через указатель) как отдельную сущность с атрибутом доступа 'запись и чтение' или 'только чтение', т.е. '*' и 'const *' (как приняли в п.2, const пишется всегда слева).

Итак, следуя этой формализации, константный указатель на константные данные типа int (или прямо - типа int константных данных константный указатель) пишется так:
Код:
int const * const p;
Компоненты: int - тип, const * - косвенность доступа (в данном случае только для чтения), const p - адрес памяти (в данном случае только для чтения).

Вообщем 'const int*' и 'int const *' это как, например, 'спиртовой раствор' и 'спирта раствор'. 1-е для обывателей, 2-е - для технарей/профи Улыбающийся, потому что здесь главное (спирт) выноситсяна первое место, например, удобно строить алфавитный указатель.
« Последнее редактирование: Апрель 20, 2021, 07:45 от AkonResumed » Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.203 секунд. Запросов: 23.