Простой вопрос о постоянном синтаксисе C ++ - PullRequest
5 голосов
/ 27 апреля 2010

Вот некоторый код, скопированный из Thinking in C ++ Vol1 Chapter 10.

   #include <iostream>
   using namespace std;

   int x = 100;

   class WithStatic {
        static int x;
        static int y;
        public:
             void print() const {
             cout << "WithStatic::x = " << x << endl;
             cout << "WithStatic::y = " << y << endl;
           }
  };

что означает const для функции print ()? Спасибо!

Ответы [ 7 ]

3 голосов
/ 27 апреля 2010

Я слышал, что это описывалось ранее как & ldquo; метод, который не изменяет логически объект & rdquo ;. Это означает, что при вызове этого метода вызывающая сторона может ожидать, что состояние объекта останется неизменным после возврата метода. По сути, указатель this становится постоянным указателем на постоянный экземпляр этого класса, поэтому переменные-члены не могут быть изменены. Исключением из этого правила является то, что переменные-члены объявлены с mutable. Если в классе есть mutable переменные-члены, они могут быть изменены как неконстантными, так и константными методами. Кроме того, неконстантные методы нельзя вызывать из константного метода.

Некоторые люди используют mutable переменные-члены для кэширования результатов своевременных вычислений. Теоретически состояние объекта не изменяется (т. Е. Единственный эффект состоит в том, что последующие вызовы выполняются быстрее, но они дают одинаковые результаты при одинаковом входе).

2 голосов
/ 27 апреля 2010

Это означает, что он не изменяет никакие переменные-члены класса.

http://www.parashift.com/c++-faq-lite/const-correctness.html

1 голос
/ 27 апреля 2010

Если функция-член объявлена ​​как «const», это означает, что функция не будет изменять состояние объекта. Это:

  • Документирует тот факт, что функция не будет изменять состояние (полезно для других разработчиков).
  • Позволяет компилятору оптимизировать, зная, что результат других "const" функций не изменится в результате вызова этой функции (что позволяет вызывать функции из циклов).
  • Позволяет вызывать функцию, когда объект передается по константной ссылке, константному указателю и т. Д.

По всем вышеперечисленным причинам, как правило, следует объявить функцию как «const», если она не изменяет логически состояние объекта. Если логическое состояние объекта изменяется, не используйте «const». Кроме того, существуют случаи, когда реальное состояние изменяется, но логическое состояние не меняется (например, кеширование), и в этом случае следует пометить функцию как «const», но необходимо использовать ключевое слово «mutable» с кешированием. переменные, чтобы сообщить компилятору, что их изменение фактически не меняет логическое состояние.

1 голос
/ 27 апреля 2010

Эффективно делает указатель this константным указателем на const вместо константного указателя на неконстантный. Таким образом, всякий раз, когда вы ссылаетесь на this в функции-члене const - явно или неявно - вы используете указатель const для const.

Итак, в случае с классом, который у вас здесь есть, в любой неконстантной функции тип this равен WithStatic const *, а в константных функциях его тип равен const WithStatic * const.

Как и в случае с любым указателем на const, вы не можете изменить ничего, на что он указывает. Таким образом, вы не можете изменить ни одну из его переменных-членов и не можете вызвать ни одну из ее неконстантных функций-членов.

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

возможно для переменных-членов, которые могут быть изменены, если они mutable или volatile, но это более сложные темы, которые, вероятно, лучше избегать, пока вы не будете лучше знакомы с языком , Конечно, вам обычно не нужно беспокоиться о них и не следует использовать их, если вам это не нужно. Также можно отбросить константность указателя this, и в этот момент вы можете изменить его, но IIRC - это неопределенное поведение, и это определенно считается плохой идеей. Так, есть случаи, когда возможно изменить состояние объекта в функции-члене const, но обычно это невозможно и лучше избегать, даже если это так.

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

1 голос
/ 27 апреля 2010

Это гарантия того, что функция не будет изменять объект вообще (то есть это функция «только для чтения»). РЕДАКТИРОВАТЬ: Очевидно, исключение из этого правила, если объект имеет mutable членов; они могут быть изменены как постоянными, так и неконстантными функциями.

Кроме того, я рад, что кто-то еще учится на TIC ++. Это отличный ресурс для начинающих.

0 голосов
/ 06 апреля 2011

Интуитивно, это означает, что метод не изменяет объект, для которого он вызывается. Но на самом деле это означает две вещи:

  • Метод может быть вызван для объекта или указателя объекта, объявленного как const.
  • В методе указатель this становится const. Следовательно, все члены (кроме объявленных mutable) const, то есть доступны только для чтения, в контексте метода. Тем не менее, он все еще может изменить:
    • данные, на которые указывают члены объекта, для которого он вызывается
    • , кроме как через указатель this, включая глобальные данные, данные, на которые указывают параметры метода, статические члены класса, другие объекты класса, даже тот же объект (если он имеет неконстантный указатель на него или обход постоянства с использованием const_cast).
0 голосов
/ 27 апреля 2010

const означает, что print () не может изменять переменные состояния, не помеченные как mutable.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...