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

Модификатор const в аргументах функций

19.07.2011, 22:29. Показов 6309. Ответов 31
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Постоянно путаюсь в этих константах. Как писать грамотнее?

Вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
     template<typename TypeT>  
void TLinePointer<TypeT>::operator = (TypeT* pObject)  //функция не меняет аргумент
{                               //по идее, просится const
    if(pObject==0) { Release(); return; }
    if(mp_Pointer != pObject)  
    {  
        Release();
        mp_Pointer = pObject; 
        mp_CounterLink=new int; 
        *mp_CounterLink=1;
        pObject=0; 
    }
}
Или вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
     template<typename TypeT>  
void TLinePointer<TypeT>::operator = (const TypeT* pObject) 
{
    if(pObject==0) { Release(); return; }
    if(mp_Pointer != pObject)  
    {  
        Release();
        TypeT* TempPointer = const_cast<TypeT*>(pObject); 
                                                      //приходится кастовать, потому что
        mp_Pointer = TempPointer;      //нельзя неконстантному указателю 
                                                      //присвоить константный напрямую
        mp_CounterLink=new int; 
        *mp_CounterLink=1;
        pObject=0; 
    }
}
Интуиция мне подсказывает, что второй вариант более правильный (хотя и приходиться совершать больше движений)

А что подскажут уважаемые эксперты? Или может быть есть ещё какие то варианты?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.07.2011, 22:29
Ответы с готовыми решениями:

Модификатор const для параметра функции не const?
void foo(const int N) { int Arr; //&lt;-- ??? } В clang это работает. В VisualStudio 2015 нет.

Const-параметры в аргументах функции
А тут уже const излишен, перебор. Добавлено через 3 минуты void setDescription(const std::string&amp; _description) {...

Модификатор доступа const
Здравсвуйте, прошу помочь с вопросом. В общем имеется такой класс: class Animator : public sf::Drawable { private: ...

31
Заблокирован
20.07.2011, 08:07  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от accept Посмотреть сообщение
таким образом он должен указывать на const
Но он может обнулиться!

Он гарантирует, что ничего не сделает с содержимом того, на что указывает.
Но с самим собой он может делать что угодно!

Добавлено через 7 минут
Цитата Сообщение от accept Посмотреть сообщение
это где-то сверху должно быть
имя типа TypeT должно быть там известно
Нет, ибо данная переменная "перемена" по задумке и логике.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
20.07.2011, 08:23
Цитата Сообщение от Bers Посмотреть сообщение
Но он может обнулиться!
Ну тут проблема была бы если бы указатель был const (а не то, на что он указывает).
Вот абсолютно нормальный код:
C++
1
2
3
4
5
6
        int a=10;
    const int* ptr;
    ptr=&a;
    std::cout<<ptr<<std::endl;
    ptr=NULL;
    std::cout<<ptr<<std::endl;
1
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
20.07.2011, 08:45
Цитата Сообщение от Bers
Но он может обнулиться!

Он гарантирует, что ничего не сделает с содержимом того, на что указывает.
Но с самим собой он может делать что угодно!
Цитата Сообщение от Bers
2. Да
похоже, что нет

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

Добавлено через 9 минут
C
1
2
3
4
    char c = 'a';
    const char cc = 'b';
 
    c = cc;
это правильно

C
1
2
3
4
5
6
7
    char c = 'a';
    char *pc;
    const char *cpc;
 
    pc = &c;
    cpc = &c;
    pc = cpc;
это неправильно

Code
1
2
3
4
[guest@localhost tests]$ .ansi t.c -o t
t.c: В функции ‘main’:
t.c:12:8: предупреждение: присваивание отменяет квалификаторы указуемого типа
[guest@localhost tests]$
1
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
20.07.2011, 08:56
Цитата Сообщение от Bers Посмотреть сообщение
/приходится кастовать, потому что //нельзя неконстантному указателю //присвоить константный напрямую
Цитата Сообщение от Bers Посмотреть сообщение
Однако! Попандос. Присвоить неконстрантному указателю значение константного нельзя
Не стоит путать константный указатель и указатель на константу.

Цитата Сообщение от Bers Посмотреть сообщение
TypeT* TempPointer = const_cast<TypeT*>(pObject);
Можно заменить на
C++
1
const TypeT * temp = pObject;
Цитата Сообщение от Bers Посмотреть сообщение
Что делать?
Я для себя давно уже решил и использую принцип максимальным ограничений. Всё что может быть private делается private. Всё что может быть const делается константным. Компилятору всё равно, а мне жить проще. Множество потенциальных ошибок просто невозможно совершить.

А вообще, почитай, что значит вот это:
C++
1
2
3
const int * a;
int * const b;
const int * const c;
Итого: Ничего плохого в const быть не может. Плохое может быть в const_cast, но его (плохого) может в нём и не быть.
1
 Аватар для xAtom
935 / 760 / 299
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
20.07.2011, 18:47
Цитата Сообщение от Deviaphan Посмотреть сообщение
Плохое может быть в const_cast, но его (плохого) может в нём и не быть
Само приведение типа, может повлиять на данные, вот пример .
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
46
47
48
49
50
51
52
53
#include <stdio.h>
 
 
void _str1(char* s) {
   while( *s )
      *s++ = 'A';
}
 
 
void _str2(const char* s) {
   char* c = (char*) s;
   while( *c )
      *c++ = 'B';
}
 
 
void _str3(char* const s) {
   char* c = (char*) s;
    while( *c )
      *c++ = 'C';
}
 
 
void _str4(const char* const s) {
    char* c = (char*) s;
    while( *c )
      *c++ = 'D';
}
 
 
 
int main(void)
{
   char s[] =  "address ptr";
 
   puts(s);
 
   _str1(s);
   puts(s);
 
   _str2(s);
   puts(s);
 
   _str3(s);
   puts(s);
 
   _str4(s);
   puts(s);
 
 
   getchar();
   return 0;
}
1
Заблокирован
20.07.2011, 19:51  [ТС]
Ну все, вразумел вроде бы. Блин... даже и не подумал бы, что столько нюансов может быть с этой константностью.

Моя идея о том, что константа - это "переменная" ONLY READ рассыпается на куски....
А жаль.... Ещё совсем вчера было намного проще жить в этом мире.

Последний вопрос:
Допустим мой Потребитель "запоминает" где живёт его Менеджер.
Внутри класса Потребителя находится указатель на объект класса Менеджера.
Поскольку внутри Потребителя никогда не будут происходить операции типа:
delete pМенеджер; pМенеджер = NULL;

Более того - и не должны происходить!
То указатель на менеджера можно (а значит и нужно) сделать константным.
Это будит означать, что Потребитель не отвечает, за время жизни своего Менеджера. И Ничего не может сделать с той областью памяти, где этот Менеджер живёт (не может его убить).

Я все правильно понял?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
20.07.2011, 20:00
Лучший ответ Сообщение было отмечено как решение

Решение

Bers, не видя всего исходника целиком сложно понять, чего конерктно ты не понимаешь или понимаешь, но не правильно. На всякий случай почитай тут Неочевидные ответы на простые вопросы раздел 4, лишним не будет

Добавлено через 27 секунд
Цитата Сообщение от xAtom Посмотреть сообщение
Само приведение типа, может повлиять на данные, вот пример
Только при этом программист - сам дурак
3
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
20.07.2011, 20:02
Константный указатель - это указатель на область памяти, которому нельзя присвоить указатель на другую область памяти.
Указатель на константу - это указатель на область памяти, которую нельзя изменить через этот указатель.
Константный указатель на константу - оба этих ограничения.
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
20.07.2011, 20:08
Цитата Сообщение от Deviaphan Посмотреть сообщение
Константный указатель - это указатель на область памяти, которому нельзя присвоить указатель на другую область памяти.
Указатель на константу - это указатель на область памяти, которую нельзя изменить через этот указатель.
Константный указатель на константу - оба этих ограничения.
Причём надо понимать, что "нельзя" в обоих случаях означает "нельзя в языке программирования". И в подавляющем большинстве случаев это означает "если очень хочется, то можно, но компилятор за последствия не отвечает". А в оставшихся случаях это действительно "нельзя", потому что тебе это не даст сделать операционная система или даже аппаратура
1
Заблокирован
20.07.2011, 20:24  [ТС]
У меня была путаница в голове, я думал что константный указатель указывает собственно на константу, а не то, что он сам по себе является константой.

Теорию проштудировал, ошибку осознал.

Если и остались ещё какие то неясности - думаю практика это исправит.

Всем огромное спасибо за участие.
Думаю, что тему можно закрыть.
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
21.07.2011, 01:43
Цитата Сообщение от Bers
Моя идея о том, что константа - это "переменная" ONLY READ рассыпается на куски....
это почему ?

C
1
2
3
4
    char c = 'a';
    const char cc = 'b';
 
    c = cc;
переменная cc как была read-only, так и осталась
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
21.07.2011, 08:18
Цитата Сообщение от xAtom Посмотреть сообщение
Само приведение типа, может повлиять на данные, вот пример
Привидение типа на данные не повлияло. Это следующее за ним присваивание повлияло.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.07.2011, 08:18
Помогаю со студенческими работами здесь

Модификатор const Очередные грабли с++?
Представленный ниже код не компилируется. В чем здесь может быть проблема? class CFirst { public: int GetValue() { return...

Модификатор const в качестве возвращаемого значения
const int get_size(const int&amp; a) { return a; } int main() { const int size = get_size(5);

Чисто виртуальные классы. Модификатор const
Приветствую всех! Известно, что чисто виртуальный (абстрактный) класс можно получить class A { public: virtual void test()=0; };...

В чем различия константных объектов и константных ссылок на объекты в аргументах функций-членов?
Как правильно необходимо указывать типы данных для входных параметров метода? Пример: void resetArguments(const int inputStrong,...

int const * const foo(const int* param) const - разъясните значение квалификаторов
int const * const foo(const int* param) const -----1------2----------3----------------4 1: ? 2: делает содержимое массива или...


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

Или воспользуйтесь поиском по форуму:
32
Ответ Создать тему
Новые блоги и статьи
Загрузка PNG-файла с альфа-каналом с помощью библиотеки SDL3_image на Android
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru