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

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

19.07.2011, 22:29. Показов 6351. Ответов 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
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru