Re: [C++] Константные методы класса и внешние объекты

lexspar

Насколько я понимаю, объявляя функцию-член класса константной, я обещаю компилятору не изменять видимое извне состояние класса.
А что будет, если константный метод меняет значение какой-либо переменной, не являющейся членом — скажем, какую-нибудь глобальную переменную?
Может ли компилятор вызывать константный метод меньшее число раз, чем указано в коде, если считает, что между вызовами функции не менялось состояние объекта, к которому этот метод применяется?
Вероятно, ответ на последний вопрос отрицателен — GCC при компиляции с -O2 все-таки оставляет такие вызовы для функций, определение которых ему неизвестно, но все же хотелось бы услышать подтверждение моему предположению.

pitrik2

Может ли компилятор вызывать константный метод меньшее число раз, чем указано в коде, если считает, что между вызовами функции не менялось состояние объекта, к которому этот метод применяется?
ну ты в курсе про const_cast и mutable?
что если твой константный метод зовет какуюнить внешнюю функцию передавая туда this константный
а та внешняя функция через const_cast весь твой объект нафик меняет?
да и потом надобности же нету
обычно константные методы довольно маленькие
это либо что-то сообщить про объект (типа жив ли он)
либо что-то мелкое посчитать (если надо считать крупное то скорее всего результаты будут кешироваться и метод перестанет быть const)
смысла запоминать результат нету, скорее стоит их заинлайнить

pitrik2

Насколько я понимаю, объявляя функцию-член класса константной, я обещаю компилятору не изменять видимое извне состояние класса.
непонятно вот это "обещаю"
я бы это назвал так: "объявляя функцию-член класса константной, я прошу компилятор сообщать мне обо всех изменениях видимого извне состояние класса"

tamusyav

обычно константные методы довольно маленькие
это либо что-то сообщить про объект (типа жив ли он)
либо что-то мелкое посчитать (если надо считать крупное то скорее всего результаты будут кешироваться и метод перестанет быть const)
смысла запоминать результат нету, скорее стоит их заинлайнить
Ну, это вопрос спорный. Например, методы, которые генерируют что-то на основе содержимого класса или сохраняют его, могут быть довольно навороченными, но не использовать кеширование, поскольку вызываются реже, чем происходит изменение класса. Мне кажется, такая ситуация - не редкость. Да и сам кеш может быть mutable.
Кстати, если уж речь зашла о глобальных объектах, то есть вариант и без const_cast и mutable:

class A {
public:
void x const;
void y;
};

A a;

void A::x const
{
a.y;
}

lexspar

ну ты в курсе про const_cast и mutable?что если твой константный метод зовет какуюнить внешнюю функцию передавая туда this константныйа та внешняя функция через const_cast весь твой объект нафик меняет?
Насчет нафиг меняния как раз интересно узнать. Дело вот в чем — если ты (используя GCC) скажешь на функцию __attribute__const или даже просто __attribute__pure т. е., пообещаешь компилятору в этой функции только посмотреть на параметры (const) или на параметры, то, куда они указывают, и глобальные переменные (pure то GCC может вызывать эту функцию меньше раз, чем написано (что проверено на практике). Даже в случае, если ты свое обещание нарушаешь, и, к примеру, пишешь по адресу, полученному как аргумент.
Так вот — не получится ли с константным методом такого же, что компилятор поверит мне в обещание не менять видимое извне состояние и будет звать метод, когда сам захочет, а не когда явно написано? Эксперимент показывает, что это не так, но хочется подтверждения более весомого, чем проверка на одном компиляторе.
скорее стоит их заинлайнить
Как раз нет — иногда быстрее воспользоваться возвращаемым значением и предполагать, что оно не будет меняться.

int count(const vector<int> &v)
{
int n = 0;
for(int i=0;i<v.size;++i)
++n;
return n;
}

Например, этот кусок кода GCC сокращает до return v.size а точнее, до результата заинлайнивания size. Здесь, правда, определение size компилятору известно.

procenkotanya

Если тебе известно про __attribute__, то не должно быть сложно и заглянуть в стандарт языка и почитать, что гарантируется относительно const методов. Кто-то здесь должен это делать за тебя?

lexspar

Если тебе известно про __attribute__, то не должно быть сложно и заглянуть в стандарт языка и почитать, что гарантируется относительно const методов. Кто-то здесь должен это делать за тебя?
Ну что ты сразу в штыки-то? Стандарт — талмуд на 1K страниц, писаный суконным языком. Мне потому и хочется сначала спросить на форуме — если кто знает о const, то наверняка его выслушать будет полезнее и быстрее, чем выискивать все то же самое в стандарте. Кроме того, помимо стандарта есть подводные камни в каждой его реализации, и про них в стандарте ничего не написано.

Serab

ну ты в курсе про const_cast и mutable?
что если твой константный метод зовет какуюнить внешнюю функцию передавая туда this константный
а та внешняя функция через const_cast весь твой объект нафик меняет?
начал за здравие :)
const_cast можно делать, только если известно, что объект неконстантный. Это очень нехорошие функции, которые конст_кастят все подряд и начинают изменять. Почему бы тогда им не получать в качестве параметра не-константу. То же самое о функциях-членах можно сказать.
Просто достаточно того, что может быть mutable и все.

Serab

что-то я сразу не заметил. Ну это же искусственный пример, где непонятно зачем глобальный объект того же типа. Топикстартер и так говорил о том, что можно поменять глобальные данные, например, просто присвоить глобальной переменной типа int другое значение.
Оставить комментарий
Имя или ник:
Комментарий: