Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
JIawliet
78 / 78 / 31
Регистрация: 20.07.2016
Сообщений: 327
Завершенные тесты: 2
#1

Указатели на константные объекты - C++

23.01.2017, 11:40. Просмотров 507. Ответов 29
Метки нет (Все метки)

Нельзя создать неконстантный указатель на константный объект по понятным причинам, но имеем такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
typedef char* pStr;
 
int main ()
{
  const char ch1 = 'a';
  //char* ptr1 = &ch;        // ошибка!
  const char* ptr2 = &ch1;   // ok
 
 
  char ch2 = 'b';
  const pStr ptr3 = &ch2;
  const pStr* ptr4 = &ptr3;  // ok! wtf???
 
  return 0;
}
в 12 строке создается неконстантный указатель на константный указатель. почему такое допускается?
http://www.cyberforum.ru/cpp-beginners/thread1649776.html
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.01.2017, 11:40
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Указатели на константные объекты (C++):

Константные объекты
#include <iostream> #include <windows.h> using namespace std; class CTest...

Константные статические объекты класса.
Здравствуйте. Есть класс "матрица" нужно задать константные матрицы такие как E...

Константные методы и объекты класса
Это необходимость, или явная подстраховка того, что бы объект (константный)...

Константные указатели в качестве аргументов функций
Вскрылся вот такой пробел в знаниях/понимании. Итак, есть предположим...

Константный указатель на константные данные (указатели)
В общем если раскомментить const то ничего не работает может кто знает как...

29
_stanislav
Рука
267 / 258 / 162
Регистрация: 16.08.2014
Сообщений: 1,229
Завершенные тесты: 2
23.01.2017, 12:21 #2
JIawliet,
typedef - это не простая подстановка. Поэтому некоторые моменты, связанные с typedef'ом, могут удивить.
Допустим, в коде объявлены какие-то такие переменные.

C++
1
const char* pX, Y, Z; //1
Через некоторое время мы решаем использовать typedef.
C++
1
typedef char* pChar; //2
И после этого переписываем первый кусок кода как
C++
1
const pChar pX, Y, Z; //3
Что неправильно, потому что первый и третий код не эквивалентны. Третий код без typedef'а будет выглядеть так.
char * const pX, * const Y, * const Z;

Тут не только Y и Z совсем не того типа, которого хотелось, но и у pX const применен к самому указателю, а не к тому, на что тот указывает. Всё это потому, что здесь
const pChar pX, Y, Z;

мы объявили pX, Y и Z константами типа pChar, а это не эквивалентно замене char* другим словом.

Поэтому в winnt.h, есть typedef'ы как для неконстантных вариантов указателей, так и для константных.

C++
1
2
typedef char* LPSTR;
typedef const char* LPCSTR;
В статье Const input parameters and typedefs нам советуют избегать typedef'ов для типов с указателями и использовать const только явно и когда он нужен.
1
JIawliet
78 / 78 / 31
Регистрация: 20.07.2016
Сообщений: 327
Завершенные тесты: 2
23.01.2017, 12:26  [ТС] #3
Цитата Сообщение от _stanislav Посмотреть сообщение
typedef - это не простая подстановка.
Я знаю. Вопрос был не об этом. Вопрос в том, что нельзя создать неконстантный указатель на константный объект, но:
C++
1
const pStr* ptr4 = &ptr3;
как раз таки и есть неконстантным указателем на константный указатель на char.
0
MrGluck
Модератор
Эксперт CЭксперт С++
7981 / 4862 / 1423
Регистрация: 29.11.2010
Сообщений: 13,237
23.01.2017, 12:48 #4
Стоит заметить, что указатель на константу и константный указатель - разные вещи. const может относиться как к типу, на который указывает указатель, так и к самому указателю.

Для простоты, я привожу пример с указателями на char, но с указателями на указатели ситуация точно такая же.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
    char a = 'a', b = 'b';
    const char *p1 = &a; // указатель на константу
    //*p1 = 'x'; // Error, константу менять нельзя
    p1 = &b; // Ok, указатель менять можно
 
    char *const p2 = &a; // константный указатель
    *p2 = 'x'; // Ok, указатель указывает не на константу
    // p2 = &b; // Error, указатель константный
 
    const char *const p3 = &a; // константный указатель на константу
    // *p3 = 'x'; // Error, константу менять нельзя
    // p3 = &b; // Error, указатель константный
}
Добавлено через 3 минуты
Цитата Сообщение от JIawliet Посмотреть сообщение
как раз таки и есть неконстантным указателем на константный указатель на char.
C++
1
2
3
4
5
6
int main()
{
    char ch2 = 'b';
    const char* ptr3 = &ch2; // неконстантный указатель на const char
    const char** ptr4 = &ptr3; // указатель на неконстантный указатель на const char
}
Добавлено через 1 минуту
C++
1
2
3
4
5
6
int main()
{
    const char ch2 = 'b';
    const char* const ptr3 = &ch2; // константный указатель на const char
    const char* const *ptr4 = &ptr3; // неконстантный указатель на константный указатель на const char
}
1
JIawliet
78 / 78 / 31
Регистрация: 20.07.2016
Сообщений: 327
Завершенные тесты: 2
23.01.2017, 12:52  [ТС] #5
Цитата Сообщение от MrGluck Посмотреть сообщение
Стоит заметить, что указатель на константу и константный указатель - разные вещи.
угу, const верхнего и нижнего уровня, знаем, проходили. Вопрос не в этом!

еще раз - нельзя создать неконстантный указатель на константный объект:
C++
1
2
const char ch1 = 'a';
char* ptr1 = &ch;        // ошибка!
но почему то, получается создать неконстантный указатель на константный указатель (хотя константный указатель это тоже объект, константный!):
C++
1
const pStr* ptr4 = &ptr3;
Цитата Сообщение от MrGluck Посмотреть сообщение
const char** ptr4 = &ptr3; // указатель на неконстантный указатель на const char
тут то все замечательно, создается неконстантный указатель на неконстантный указатель на константу, а я говорю про создание неконстантного указателя на константный указатель (чего быть в природе не должно!)
0
_stanislav
Рука
267 / 258 / 162
Регистрация: 16.08.2014
Сообщений: 1,229
Завершенные тесты: 2
23.01.2017, 12:55 #6
JIawliet, сам указатель это тоже объект, который можно или нельзя изменять.
0
JIawliet
78 / 78 / 31
Регистрация: 20.07.2016
Сообщений: 327
Завершенные тесты: 2
23.01.2017, 12:59  [ТС] #7
Цитата Сообщение от _stanislav Посмотреть сообщение
сам указатель это тоже объект, который можно или нельзя изменять.
золотые слова, я об этом и говорю. почему тогда можно создать неконстантный (без const нижнего уровня) указатель на константный (с const верхнего уровня) указатель?
0
_stanislav
Рука
267 / 258 / 162
Регистрация: 16.08.2014
Сообщений: 1,229
Завершенные тесты: 2
23.01.2017, 13:01 #8
Цитата Сообщение от JIawliet Посмотреть сообщение
а я говорю про создание неконстантного указателя на константный указатель (чего быть в природе не должно!)
если указатель на указатель константный, это не говорит о том что указатель на который он указывает нельзя изменять, это говорит о том что нельзя изменять его, а у указателя на который он указывает свои правила.
0
Mirmik
techpriest
220 / 191 / 53
Регистрация: 27.02.2014
Сообщений: 1,018
23.01.2017, 13:15 #9
НЕКОНСТАНТНЫЙ указатель на КОНСТАНТНЫЕ данные МОЖЕТ быть изменен, но через него НЕЛЬЗЯ изменить данные. const int*
КОНСТАНТНЫЙ указатель на НЕКОНСТАНТНЫЕ данные НЕ МОЖЕТ быть изменен, но через него МОЖНО изменить данные. int* const
КОНСТАНТНЫЙ указатель на КОНСТАНТНЫЕ данные НЕ МОЖЕТ быть изменен, и через него НЕЛЬЗЯ изменить данные. const int* const
НЕКОНСТАНТНЫЙ указатель на НЕКОНСТАНТНЫЕ данные МОЖЕТ быть изменен, и через него МОЖНО изменить данные. int*

Если сюда дописать еще указатели второго уровня, получаем уже восемь вариантов поведения.

Добавлено через 11 минут
а я говорю про создание неконстантного указателя на константный указатель (чего быть в природе не должно!)
Важно понимать, что С++ дает механизм, не ограничивая способы его применения.
Это сейчас вам может показаться, что "неконстантный указатель на константный указатель" - это что-то, чего быть не должно. Но рано или поздно они могут вам пригодится.

const защищает от модификации только ту переменную, к которой он привязан. Ему дела нет до того, чем является эта переменная. Если эта переменная - указатель на другую переменную, const ни в коем случае не распространит на нее свое действие.
0
DrOffset
7517 / 4513 / 1097
Регистрация: 30.01.2014
Сообщений: 7,362
23.01.2017, 13:47 #10
Цитата Сообщение от JIawliet Посмотреть сообщение
в 12 строке создается неконстантный указатель на константный указатель. почему такое допускается?
Непонятно что тебя удивляет.
Вот константа:
C++
1
const char a = 'a';
Вот для нее указатель (на константу):
C++
1
const char * aPtr = &a;
Вот константный указатель:
C++
1
char * const bPtr = 0;
Вот для него указатель (на константу)
C++
1
char * const * bPPtr = &bPtr;
0
MrGluck
Модератор
Эксперт CЭксперт С++
7981 / 4862 / 1423
Регистрация: 29.11.2010
Сообщений: 13,237
23.01.2017, 13:49 #11
Цитата Сообщение от JIawliet Посмотреть сообщение
а я говорю про создание неконстантного указателя на константный указатель
Я же привёл пример
Цитата Сообщение от MrGluck Посмотреть сообщение
C++
1
const char* const *ptr4 = &ptr3; // неконстантный указатель на константный указатель на const char
Указатель тоже может быть константным или нет. И это стоит учитывать при создании указателя на него. Вы же создаёте неконстантный указатель на неконстантный указатель. Смотрите на const после первой звёздочки.
Тип, на который указывает указатель можно определить как то, что идёт до звёздочки.
При записи
C++
1
const char* const *ptr4 = &ptr3
тип ptr4 - указатель на const char* const, то есть всё то, что идёт до второй звёздочки (читать надо справа налево)
тип на который указывает ptr4 - константный, второй const относится к нему. Указатель, на который указывает ptr4 имеет тип const char то есть всё то, что идёт до первой звёздочки.
0
DemolitionMan
129 / 155 / 87
Регистрация: 06.04.2016
Сообщений: 992
23.01.2017, 14:05 #12
Цитата Сообщение от JIawliet Посмотреть сообщение
//char* ptr1 = &ch; *//ошибка!
- так конечно ошибка. ch1, а не ch.
0
JIawliet
78 / 78 / 31
Регистрация: 20.07.2016
Сообщений: 327
Завершенные тесты: 2
23.01.2017, 14:11  [ТС] #13
Все как будто сговорились

C++
1
2
3
4
const char ch = 'a';  // const верхнего уровня
char* ptr = &ch;      // ошибка (обычный указатель не может указывать на объект с const верхнего уровня)
char* const ptr = &ch;  // ошибка (const верхнего уровня (aka константный указатель))
const char* ptr = &ch;    // ок (const нижнего уровня)
ch - наш константный объект, на него не может указывать указатель без const нижнего уровня. Все ясно-понятно, едем дальше:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
typedef char* pStr;
 
const char ch = 'a';
//const pStr ptr = &ch;  // ошибка (aka char* const / aka const верхнего уровня)
 
/*
 *   ptr в свою очередь тоже объект,
 *   как и ch. У ch const верхнего уровня
 *   и у ptr const верхнего уровня
 */
 
// тогда почему допустим такой код????
const pStr ptr = nullptr;
const pStr* pptr = &ptr;    // обычный указатель без const верхнего и нижнего уровня
                            // указывает на константный объект!!!!
Добавлено через 5 минут
Цитата Сообщение от DrOffset Посмотреть сообщение
Непонятно что тебя удивляет.
вот то и удивляет, что обычный указатель указывает на константный объект
Цитата Сообщение от DrOffset Посмотреть сообщение
char * const * bPPtr = &bPtr;
0
Mirmik
techpriest
220 / 191 / 53
Регистрация: 27.02.2014
Сообщений: 1,018
23.01.2017, 14:11 #14
const pStr раскрывается в char* const
const pStr* раскрывается в char* const *

char* const - это константный указатель на char.
char* const * - это указатель на константный указатель на char.
0
JIawliet
78 / 78 / 31
Регистрация: 20.07.2016
Сообщений: 327
Завершенные тесты: 2
23.01.2017, 14:13  [ТС] #15
Цитата Сообщение от Mirmik Посмотреть сообщение
const pStr раскрывается в char* const
const pStr* раскрывается в char* const *
char* const - это константный указатель на char.
char* const * - это указатель на константный указатель на char.
вы издеваетесь надо мной??? я тоже самое написал! я вам о мягком, а вы мне о теплом
0
Mirmik
techpriest
220 / 191 / 53
Регистрация: 27.02.2014
Сообщений: 1,018
23.01.2017, 14:13 #16
Я думаю, вас путает терминология указатель верхнего, нижнего уровня.
Этих уровней может быть сколько угодно.

char* const * - здесь три уровня.
0
JIawliet
78 / 78 / 31
Регистрация: 20.07.2016
Сообщений: 327
Завершенные тесты: 2
23.01.2017, 14:13  [ТС] #17
Mirmik,
Цитата Сообщение от JIawliet Посмотреть сообщение
const pStr ptr = &ch; *// ошибка (aka char* const / aka const верхнего уровня)
0
Mirmik
techpriest
220 / 191 / 53
Регистрация: 27.02.2014
Сообщений: 1,018
23.01.2017, 14:15 #18
Что удивительного в неконстантном указателе на константные данные?
0
JIawliet
78 / 78 / 31
Регистрация: 20.07.2016
Сообщений: 327
Завершенные тесты: 2
23.01.2017, 14:17  [ТС] #19
Mirmik, ничего меня не путает, есть четкий вопрос: почему можно создать указатель (без!!! const верхнего и нижнего уровня) на константный (с const верхнего уровня) объект????

а как все раскрывается и расшифровывется, я написал сверху в своем коде с комментариями, если в коде или комментариях к нему есть ошибка - поправьте

Добавлено через 1 минуту
Цитата Сообщение от Mirmik Посмотреть сообщение
Что удивительного в неконстантном указателе на константные данные?
что удивительного? да в том что их нельзя создавать!

C++
1
2
const int SZ = 100;
int* ptr = &SZ;   // ERROR!
0
Mirmik
techpriest
220 / 191 / 53
Регистрация: 27.02.2014
Сообщений: 1,018
23.01.2017, 14:21 #20
Верхний и нижний уровень - это крайне плохая терминология.

Вы написали:
C++
1
2
const pStr ptr = nullptr;
const pStr* pptr = &ptr;
Если я обозначу const pStr как type, я получу
C++
1
2
type ptr = nullptr;
type* pptr = &ptr;
Вот именно это тут и происходит. Создается указатель... На переменную какого-то типа. А является он константным или нет, совершенно не важно.
1
23.01.2017, 14:21
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.01.2017, 14:21
Привет! Вот еще темы с решениями:

Как правильно объявлять статические константные объекты в классе?
В классе надо объявить статичные константные строки. Типа class A { public:...

Константные и не константные ссылки. Приведения типов. Нужно уточнение
Не очень понимаю в чем различие (2,3 строчки). int x = 10; double &y =...

Указатели на объекты
имеется класс Users и массив указателей на класс Users* userq у класса Users...

Указатели на объекты
Здравствуйте! Есть класс, назовем его Some. Он содержит указатель на объект...


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

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

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