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

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

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

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

Вот так:
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)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.07.2011, 22:29
Ответы с готовыми решениями:

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

Const-параметры в аргументах функции
А тут уже const излишен, перебор. Добавлено через 3 минуты void setDescription(const...

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

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

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

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

Добавлено через 7 минут
Цитата Сообщение от accept Посмотреть сообщение
это где-то сверху должно быть
имя типа TypeT должно быть там известно
Нет, ибо данная переменная "перемена" по задумке и логике.
0
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,116
Записей в блоге: 2
20.07.2011, 08:23 22
Цитата Сообщение от 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 23
Цитата Сообщение от 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;
это неправильно

Код
[guest@localhost tests]$ .ansi t.c -o t
t.c: В функции ‘main’:
t.c:12:8: предупреждение: присваивание отменяет квалификаторы указуемого типа
[guest@localhost tests]$
1
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
20.07.2011, 08:56 24
Цитата Сообщение от 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
935 / 760 / 299
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
20.07.2011, 18:47 25
Цитата Сообщение от 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  [ТС] 26
Ну все, вразумел вроде бы. Блин... даже и не подумал бы, что столько нюансов может быть с этой константностью.

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

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

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

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

Решение

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

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

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

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

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

C
1
2
3
4
    char c = 'a';
    const char cc = 'b';
 
    c = cc;
переменная cc как была read-only, так и осталась
0
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
21.07.2011, 08:18 32
Цитата Сообщение от xAtom Посмотреть сообщение
Само приведение типа, может повлиять на данные, вот пример
Привидение типа на данные не повлияло. Это следующее за ним присваивание повлияло.
0
21.07.2011, 08:18
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.07.2011, 08:18
Помогаю со студенческими работами здесь

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
32
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru