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

Модификатор const Очередные грабли с++?

21.10.2011, 21:15. Показов 6704. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Представленный ниже код не компилируется.
В чем здесь может быть проблема?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class CFirst
{
public:
    int GetValue() { return 10; }
};
 
class CSecond
{
public:
    void Do(const CFirst& src) const
    {
        if(src.GetValue()==10) { std::cout<<"YES!\n"; }
    }
};

error C2662: CFirst::GetValue: невозможно преобразовать указатель 'this' из 'const CFirst' в 'CFirst &'

Если убрать модификатор const все работает без проблем.
Я уже заколебался ловить баги с этими констами.
Оказывается, они даже жизнь временных объектов умеют продлевать.
Но здесь же в условии сам объект класса CFirst вообще не трогается.
Число 10 сравнивается с временным int, и контракт CFirst не нарушается!
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
21.10.2011, 21:15
Ответы с готовыми решениями:

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

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

Модификатор const в аргументах функций
Постоянно путаюсь в этих константах. Как писать грамотнее? Вот так: template&lt;typename TypeT&gt; void...

12
Эксперт С++
516 / 421 / 92
Регистрация: 23.09.2010
Сообщений: 1,165
21.10.2011, 21:18
C++
1
2
3
4
5
class CFirst
{
public:
    int GetValue() const { return 10; }
};
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
21.10.2011, 21:19
Цитата Сообщение от Bers Посмотреть сообщение
int GetValue() { return 10; }
компилятору не в домёк что эта функция не меняет состояние объекта потому
Цитата Сообщение от Bers Посмотреть сообщение
error C2662: CFirst::GetValue: невозможно преобразовать указатель 'this' из 'const CFirst' в 'CFirst &'
все законно
0
237 / 210 / 29
Регистрация: 08.06.2011
Сообщений: 467
21.10.2011, 21:20
src - объявлен как ссылка на константный объект, а значит к этому объекту могут быть применены только константные методы, которым GetValue не является
0
Эксперт С++
516 / 421 / 92
Регистрация: 23.09.2010
Сообщений: 1,165
21.10.2011, 21:20
Все как раз четко. Откуда компилятор знает, что происходит в CFirst::GetValue(). ИИ не наделен пока.
0
Заблокирован
21.10.2011, 21:29  [ТС]
Цитата Сообщение от Jupiter Посмотреть сообщение
компилятору не в домёк что эта функция не меняет состояние объекта потому
ааа.... Но он же как то умеет фиксить нарушения контрактов аля int GetValue() const { return 10; }

Значит он умеет определять может ли функция изменить состояние объекта, или нет.

Добавлено через 46 секунд
Цитата Сообщение от gooseim Посмотреть сообщение
Все как раз четко. Откуда компилятор знает, что происходит в CFirst::GetValue(). ИИ не наделен пока.
Если функция нарушит контракт int GetValue() const;
Он же об этом как то узнает

Добавлено через 5 минут
А вот в этом случае что можно сделать? Снимать константность?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class CFirst
{
    int LastError;
    void CheckError() { LastError=1; }
public:
    int GetValue()  
    { 
        CheckError();
        return 10; 
    }
 
};
 
class CSecond
{
public:
    void Do(const CFirst& src) const
    {
        if(10==src.GetValue()) { std::cout<<"YES!\n"; }
    }
};
У меня нет возможности сделать метод int GetValue() const
Потому что CheckError() всегда может изменить состояние объекта.
0
Эксперт С++
516 / 421 / 92
Регистрация: 23.09.2010
Сообщений: 1,165
21.10.2011, 21:33
Цитата Сообщение от Bers Посмотреть сообщение
Если функция нарушит контракт int GetValue() const;
Он же об этом как то узнает
А если эта функция не в исходнике а в библиотеке?

Добавлено через 1 минуту
Решение простое:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class CFirst
{
    mutable int LastError;
    void CheckError() const { LastError=1; }
public:
    int GetValue() const
    { 
        CheckError();
        return 10; 
    }
 
};
 
class CSecond
{
public:
    void Do(const CFirst& src) const
    {
        if(10==src.GetValue()) { std::cout<<"YES!n"; }
    }
};
2
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
21.10.2011, 21:38
Цитата Сообщение от Bers Посмотреть сообщение
ааа.... Но он же как то умеет фиксить нарушения контрактов аля int GetValue() const { return 10; }
Значит он умеет определять может ли функция изменить состояние объекта, или нет.
все его умение заключается в отслеживании модификатора const для методов

Добавлено через 1 минуту
вот еще один пример валидного кода
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class CFirst
{
public:
    constexpr int GetValue() { return 10; }
};
 
class CSecond
{
public:
    void Do(const CFirst& src) const
    {
        if(src.GetValue()==10) { std::cout<<"YES!\n"; }
    }
};
возвращаемое значение вычислимо на этапе компиляции - следовательно оно не может изменить состояние объекта

Добавлено через 40 секунд
http://liveworkspace.org/code/... 6fe44adee0
1
Заблокирован
21.10.2011, 21:46  [ТС]
Цитата Сообщение от Jupiter Посмотреть сообщение
возвращаемое значение вычислимо на этапе компиляции - следовательно оно не может изменить состояние объекта
Утром вычислимое, к вечеру уже может и не вычисляться)
1
237 / 210 / 29
Регистрация: 08.06.2011
Сообщений: 467
21.10.2011, 21:47
Цитата Сообщение от Bers Посмотреть сообщение
Потому что CheckError() всегда может изменить состояние объекта.
Тогда зачем делать константным src, если известно что он может быть изменен?
0
Заблокирован
21.10.2011, 21:51  [ТС]
Цитата Сообщение от Net_Wanderer Посмотреть сообщение
Тогда зачем делать константным src, если известно что он может быть изменен?
метод void Do(const CFirst& src) const
заключает контракт с классом CFirst, обещая ему, что никогда, ни при каких обстоятельствах не попытается изменить состояние объекта src

То, что src может изменится сам (его внутренняя работа. Может там в другом потоке с ним кто-то что делает) - метода Do() вообще никак не касается.


И ещё: СВЯТАЯ ИНКАПСУЛЯЦИЯ. Класс CSecond разрабатывает совсем другой человек, который понятия не имеет, как устроен изнутри CFirst
CFirst сам должен позаботится о том, что бы не создавать проблем конечным пользователям
0
Эксперт С++
516 / 421 / 92
Регистрация: 23.09.2010
Сообщений: 1,165
21.10.2011, 23:07
Цитата Сообщение от Bers Посмотреть сообщение
заключает контракт с классом CFirst, обещая ему, что никогда, ни при каких обстоятельствах не попытается изменить состояние объекта src
void Do(const CFirst& src) const - указывает на то, что объект не изменит себя
void Do(const CFirst& src) const - указывает на то, что объект src константный, т.е. который не изменяется ни сам, ни при помощи кого-то, а не то, что данный метод не будет его изменять

Добавлено через 2 минуты
Цитата Сообщение от Bers Посмотреть сообщение
И ещё: СВЯТАЯ ИНКАПСУЛЯЦИЯ. Класс CSecond разрабатывает совсем другой человек, который понятия не имеет, как устроен изнутри CFirst
CFirst сам должен позаботится о том, что бы не создавать проблем конечным пользователям
Это правильно. Поэтому нужно изначально правильно его проектировать.
0
Заблокирован
21.10.2011, 23:13  [ТС]
Цитата Сообщение от gooseim Посмотреть сообщение
void Do(const CFirst& src) const - указывает на то, что объект src константный, т.е. который не изменяется ни сам, ни при помощи кого-то, а не то, что данный метод не будет его изменять
ну.. я очень надеюсь, что mutable спасет отца русской демократии))
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.10.2011, 23:13
Помогаю со студенческими работами здесь

Модификатор 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; };...

Очередные грабли I2C STM32f030
Не получается читать с EEPROM I2C. При включении первое считывание происходит правильно, а в следующих выводит непонятно что. Причем в...

очередные грабли - запрос UPDATE
Да простят меня все присутствующие - я только учусь :) Задача : загужаем в datargid данные из БД, в имеющихся данных изменяем любое...

Очередные пракозни "мвд" или очередные вкладки браузеров
Как обычно лог во вложении.


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
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 и т. д. Сборка примера Скачайте. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru