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

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

19.07.2011, 22:29. Показов 6302. Ответов 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
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
19.07.2011, 22:32
Bers, Вообще const есть const... А вы присваиваете этот указатель другому => две переменные указывают на 1 адрес... В функции-то он конечно не меняется... Так что спорно. Я бы писал const.

Ну и вообще имхо резоннее делать через swap или же как в auto_ptr к примеру.

C++
1
2
3
4
5
    auto_ptr<_Ty>& operator=(auto_ptr<_Ty>& _Right) _THROW0()
        {   // assign compatible _Right (assume pointer)
        reset(_Right.release());
        return (*this);
        }
1
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
19.07.2011, 22:32
а mp_Pointer - член класса?
1
Заблокирован
19.07.2011, 22:35  [ТС]
Цитата Сообщение от ForEveR Посмотреть сообщение
Bers, Вообще const есть const... А вы присваиваете этот указатель другому => две переменные указывают на 1 адрес... В функции-то он конечно не меняется... Так что спорно. Я бы писал const.
Вот и я так же подумал. Просто интересно, как люди делают в подобных случаях. Таки и прибегают к кастованию? Или как то покрасивее можно сделать?

Цитата Сообщение от Maxwe11 Посмотреть сообщение
а mp_Pointer - член класса?
ага
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
19.07.2011, 22:42
Цитата Сообщение от ForEveR Посмотреть сообщение
В функции-то он конечно не меняется
не меняется, но адресочек то копируется, а const с толку может сбить стороннего читателя)
1
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
19.07.2011, 22:45
Не зная реализации трудно подсказать но все же...

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template<class TypeT>
TLinePointer& TLinePointer<TypeT>::operator =(const TypeT* pointer)
{
    if (pointer == 0)
    {
        Release();
        return *this;
    }
    TLinePointer<TypeT> temp(pointer);
    swap(temp);
    mp_CounterLink = new int(1);
    pObject = 0;
    return *this;
}
Хотя я абсолютно не понимаю смысла этого кода... Видимо потому что не вижу функции Release().
1
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
19.07.2011, 22:46
Цитата Сообщение от ForEveR Посмотреть сообщение
А вы присваиваете этот указатель другому => две переменные указывают на 1 адрес... В функции-то он конечно не меняется... Так что спорно. Я бы писал const.
ForEveR, либо я тебя не понял, либо ты ошибаешься.

Елси я правильно понял, предлагается такой вариант:
C++
1
2
3
4
5
6
7
8
9
10
11
12
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; 
    }
}
Тогда либо не скомпилируется, либо члены mp_Pointer и mp_CounterLink придется объявлять как mutable.
1
Заблокирован
19.07.2011, 22:46  [ТС]
а... сорри народ. Там 14 строчки на самом деле нету (забыл убрать, когда сюда копипастил)

Цитата Сообщение от ForEveR Посмотреть сообщение
Ну и вообще имхо резоннее делать через swap или же как в auto_ptr к примеру.
В данном случае это не подходит. Источник не обнуляется.
Да и указатели, что в аргументе, что внутри класса - самые обычные
0
19.07.2011, 22:49

Не по теме:

А, все понял. Это я в суть дела невъехал))
сори...

1
Заблокирован
19.07.2011, 22:54  [ТС]
Суть в том, что если функция использует свои аргументы только для чтения, то идеологически их нужно объявлять константами. (правило хорошего тона. Хотя лично мне оч не нравится. Но вот, приходится приучать себя)

Но моя функция действительно только читает значение аргумента.
Однако! Попандос. Присвоить неконстрантному указателю значение константного нельзя.

Что делать? Я только два варианта придумал: либо послать константы нафег (раньше я всегда так и делал), либо использовать кастование.

Оба варианта - рабочие, вопрос в том, какой более грамотный?
Или может быть вообще, православные люди делают как то иначе?
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
19.07.2011, 23:23
Bers, дико непривычная сигнатура. опер присваивания ничего не возвращающий...
1
237 / 210 / 29
Регистрация: 08.06.2011
Сообщений: 467
19.07.2011, 23:36
Цитата Сообщение от Bers Посмотреть сообщение
Суть в том, что если функция использует свои аргументы только для чтения, то идеологически их нужно объявлять константами. (правило хорошего тона. Хотя лично мне оч не нравится. Но вот, приходится приучать себя)
Если используется const, то вызов функции должен проходить абсолютно безопасно(в смысле изменения) для её параметров, а здесь, хоть функция сама их и не изменяет, но присваивает адрес тем самым создает условия для дальнейшего их изменения. Так что я бы const не использовал.
1
Заблокирован
20.07.2011, 05:47  [ТС]
Цитата Сообщение от ForEveR Посмотреть сообщение
Bers, дико непривычная сигнатура. опер присваивания ничего не возвращающий...
это запрет на конструкции типа А=В=С

Добавлено через 6 часов 1 минуту
Цитата Сообщение от Net_Wanderer Посмотреть сообщение
Если используется const, то вызов функции должен проходить абсолютно безопасно(в смысле изменения) для её параметров, а здесь, хоть функция сама их и не изменяет, но присваивает адрес тем самым создает условия для дальнейшего их изменения. Так что я бы const не использовал.
Я подумал, и решил, что вы правы. Ели функция не может дать 100% гарантии, что значение константы не изменится, то конст_каст здесь больше смахивает на лёгкий хак с целью нарушить гарантии функции.

И применять его стоит только тогда, когда без него вообще никак не обойтись...
0
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
20.07.2011, 06:35
Цитата Сообщение от Bers Посмотреть сообщение
это запрет на конструкции типа А=В=С
Этот запрет делается опять возвратом const...
C++
1
const Sometype& operator=(const Sometype& r);
1
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
20.07.2011, 07:08
C++
1
TypeT* TempPointer = const_cast<TypeT*>(pObject);
C++
1
const TypeT *TempPointer = pObject;
C++
1
mp_Pointer = TempPointer;
если mp_Pointer указывает на меняемые данные, то тогда непонятно, почему адрес неизменных данных копируется в переменную-указатель, используемую для изменения данных
1
Заблокирован
20.07.2011, 07:32  [ТС]
Цитата Сообщение от accept Посмотреть сообщение
если mp_Pointer указывает на меняемые данные, то тогда непонятно, почему адрес неизменных данных копируется в переменную-указатель, используемую для изменения данных
Суть в том, что извне приходит адрес объекта. И с этим объектом ничего не должно случиться.
mp_Pointer лишь хранит этот адрес. и все. Больше ничего не делает.

Более того, объект класса может избавиться от объекта (обнулить свой mp_Pointer)
Но это никак не должно коснуться того объекта, чей адрес помнит mp_Pointer


Если туманно и не понятно, я могу выложить больше инфы и кода. Я просто не хочу напрягать читателей обилием букв и кода

Добавлено через 4 минуты
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Этот запрет делается опять возвратом const...
Я всесторонне изучу этот момент...
Правда я не понимаю, для чего, что бы запретить действие возвращать нечто в виде константы?
По моему, проще просто запретить...
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
20.07.2011, 07:42
Цитата Сообщение от Bers
mp_Pointer лишь хранит этот адрес
я так понял, что он в классе
если через него не меняются данные, то он должен указывать на const

Цитата Сообщение от Bers
Более того, объект класса может избавиться от объекта (обнулить свой mp_Pointer)
сам указатель не const

C++
1
const TypeT *TempPointer;
C++
1
const TypeT *const TempPointer;
знаешь разницу ?
1
71 / 76 / 9
Регистрация: 30.06.2011
Сообщений: 176
20.07.2011, 07:47
Цитата Сообщение от Bers Посмотреть сообщение
Более того, объект класса может избавиться от объекта (обнулить свой mp_Pointer)
Но это никак не должно коснуться того объекта, чей адрес помнит mp_Pointer
Тогда объявите указатель на константу
C++
1
const TypeT *TempPointer;
Здесь сам указатель можно менять, но не данные, на которые он указывает.
C++
1
TypeT * const TempPointer;
А вот здесь всё наоборот, указатель нельзя менять, но можно менять данные на которые он указывает
1
Заблокирован
20.07.2011, 07:57  [ТС]
Цитата Сообщение от accept Посмотреть сообщение
я так понял, что он в классе
если через него не меняются данные, то он должен указывать на const

1. Он никак не изменяет состояние объекта о котором "помнит".
Но он может к примеру "забыть все". Объект от этого никак не пострадает, просто mp_Pointer обнулиться. Тобишь, mp_Pointer так же гарантированно используется исключительно для чтения, либо обнуляется. Это гарантирует программист.

2. Да

Добавлено через 4 минуты
An1ka, милая, вы не поняли о чём речь.
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
20.07.2011, 07:57
Цитата Сообщение от Bers
Тобишь, mp_Pointer так же гарантированно используется исключительно для чтения
таким образом он должен указывать на const

C++
1
const TypeT *mp_Pointer;
это где-то сверху должно быть
имя типа TypeT должно быть там известно
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.07.2011, 07:57
Помогаю со студенческими работами здесь

Модификатор 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: делает содержимое массива или...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Воспроизведение звукового файла с помощью 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
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru