1

I've just started reading about template classes in C++ and I have come across some syntax I'm unaware of. A class method is prototyped as:

template <class Type> class Range {
            ....
        bool Below    (const Type& value) const;
            ....
}

and defined as:

template <class Type> bool Range<Type>::Below(const Type& Value) const {

    if (Value < Lo) return true;
    return false;
}

Can anyone help me understand the meaning of the 'const' flag after the method inputs have been listed? I understand there use when put before an input but not after. Cheers, Jack

JMzance
  • 1,704
  • 4
  • 30
  • 49
  • 1
    Nothing to do with templates. When constructing a [testcase](http://sscce.org) you'd have found that this is simply a feature of member functions. – Lightness Races in Orbit Jan 06 '14 at 17:48
  • const can sometimes be confusing unless you know WHY you're using it. In addition to the good answers here, read up on programming defensively, [const-correctness](http://stackoverflow.com/questions/136880/sell-me-on-const-correctness) – mungflesh Jan 06 '14 at 17:56

4 Answers4

9

In const member functions a top level const qualifier is applied to each member of the class, unless the member is marked as mutable (which means never const).

You can also have volatile member functions and both volatile and const.

Note, that for pointers and references the behaviour may be surprising:

struct X {
    int a;
    int* pa;
    int& ra;
    X() 
        : a(1)
        , pa(&a) 
        , ra(a)
    {}

    void foo() const {
        *pa = 2; // Ok, this is the pointer being const, not the value being pointed to.
        ra = 3; // Ok, this is the reference being const, not the value being referenced.
        a = 4; // Error, a is const
        pa = &a; // Error, pa is const.
    }
};

Below is how top level const qualifier is applied:

  • int becomes int const - a constant integer.
  • int* becomes int* const - a constant pointer, not int const* - a pointer to constant.
  • int& becomes int& const - a constant reference, not int const& - a reference to constant. Applying const to references does not do anything, because they can not be changed to refer to another object anyway.

Another way to think about this, is that in non-const member functions this has the type of X* const, whereas in const member functions this is X const* const. Note how this pointer is always constant.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
3

Const after a method means that the method itself is constant, and in fact will have a constant 'this' pointer. In basic terms it means that method is not allowed to make changes to the state of the class (member variables). This allows the compiler to optimize on this fact, and tells other developers that the method will not be making state changes.

There are ways to get around this rule in C++, such as the 'mutable' keyword and const_cast, but really you shouldn't try and break const correctness unless you really, really know what you're doing.

Matt Holmes
  • 1,055
  • 1
  • 8
  • 22
  • I'm not sure if the compiler is allowed to do optimizations, as we're allowed to have `mutable` members. – leemes Jan 06 '14 at 17:38
  • The compiler will do optimizations unless 'mutable' is used. Compilers are smart enough to know when a class has mutable members and when it does not. Trust me, compilers optimize against const methods. – Matt Holmes Jan 06 '14 at 17:39
3

This means the method is const. The method cannot change the state of the object it is called upon. If you change variables in this method, you will get a compiler error.

Only methods declared const can be called on a const object, because they are guaranteed to not change it.

nvoigt
  • 75,013
  • 26
  • 93
  • 142
1

Compilers implicitly pass a pointer to the object as an argument of a non-static member. It is named this in the function definition. The qualifier const means that this pointer this has the qualifier const. That is it is applied to the pointer this.

leemes
  • 44,967
  • 21
  • 135
  • 183
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • And that would make pointer `this` const (i.e. `X* const`), not the value pointed to. Note that `this` is always const, you can not reassign it. My favourite interview question is `typedef char* P; typedef const P Q; typedef P const V`, what are `Q` and `V`? – Maxim Egorushkin Jan 06 '14 at 17:57
  • @Maxim Yegorushkin Maybe my description is not clear but I meant const SomeClass *. – Vlad from Moscow Jan 06 '14 at 18:04
  • Compilers apply cv-qualifiers on the right, in fact, so what you said is `SomeClass* const`. This is the reason some people write `int const` instead of confusing `const int`. – Maxim Egorushkin Jan 06 '14 at 18:07