Is it good style to declare functions as "const"?

I sometimes see a function declared as "const"...

eg. int GetCount() const {return m_count;};

However, I've never used it, and to me it looks like it adds little value.

Does it add any value? Would you recommend that I use "const" whenever it is applicable (particularly for "Get" functions such as this)?

Ta,

Javaman
Javaman59Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

danydCommented:
a const member function tells the programmer that that function will not modify its object.  It promises - and the compiler will enforce it - that none of the object's state will be modified by that function.

It is a good part of "programming by contract" design and you should use it whenever that is really your intention.

It *may* also allow the compiler to do certain optimisations, but that is only a secondary reason for using it.
rajeev_devinCommented:
This is for your information.
A const function can modify the mutable variable of an object.

Example:
class A
{
public:
   void f() const { x = 100;} // This is valid.
private:
   mutable int x;
};

Check this link for more details
http://msdn2.microsoft.com/en-us/library/4h2h0ktk(VS.80).aspx
AxterCommented:
>>Does it add any value?

Yes.
It adds value in that if you have a constant object, you can still call that function if the function is const.

Example:
void SomeFunc(const std::string &const_obj)
{
  cout << const_obj << endl;


If std::string did not have a constant operator, the above line of code would give a compile error.

Fundamentals of JavaScript

Learn the fundamentals of the popular programming language JavaScript so that you can explore the realm of web development.

itsmeandnobodyelseCommented:
>>>> If std::string did not have a constant operator,
>>>> the above line of code would give a compile error.

It is not the cout line that would give an error but the call of SomeFunc if the argument was defined without const:

void SomeFunc(std::string &const_obj)
{
  cout << const_obj << endl;
}

compiles,  but

    const string str = "Hello World";
    SomeFunc(str);   // compile error

would fail to compile.

Actually, the question asked for the value of the 'const' attribute of member functions rather than const argument types. First, only member functions can be declared as const. Second, if a member function is defined as const you know fo sure that it doesn't change any (data) member *and* that it doesn't call any non-const member function. At the first glance it might look like that adds little value. Moreover, if you are implementing a non-trivial const function you might experience that you can't call even trivial member function where the const attribute was missing. So, to get it compiled you need to add the const attribute to more and more other routines. But if once done, you have the benefit that your member functions were well designed and that there isn't a *get* function that surprisingly modifies some data members or calls a complex model-changing member function.

Regards, Alex


AxterCommented:
>>Actually, the question asked for the value of the 'const' attribute of member functions rather than const argument types.

And that's what I was referring to.

>>It is not the cout line that would give an error but the call of SomeFunc if the argument was defined without const:
You're reading this in the wrong context.

Example code:
void SomeFunc(const std::string &const_obj);

const string str = "Hello World";
SomeFunc(str);   //This will NOT give you a compile error, because there's nothing wrong with it

void SomeFunc(const std::string &const_obj)
{
  cout << const_obj << endl; //This WILL give you a compile error **IF** the string operator did NOT have a const function

The above line will not give you a compile error, becaue string operator is const, but if it was not, then it would give you a compile error.

Example code with type that does not have constant.

class foo
{
 public:
  int SomeNonConstFunction(){return 123;}
};

void SomeFunc(const foo &const_obj)
const foo const_obj;
SomeFunc(const_obj);//This will NOT give you a compile error, because there's nothing wrong with it

void SomeFunc(const foo &const_obj)
{
  cout << const_obj.SomeNonConstFunction() << endl;//This WILL give you a compile error, because SomeFunc is NOT a const function
itsmeandnobodyelseCommented:
>>>> **IF** the string operator

What string operator are you referring to? Do you mean "ostream& operator<<(ostream&, const string&)" ?

Actually, I am a little bit confused why the fact that most operator functions of STL were defined as const should give a reason to define private member functions as const as well.

>>>> cout << const_obj.SomeNonConstFunction() give you a compile error

Yes, of course. But it would not compile because of "const_obj.SomeNonConstFunction()" regardless whether there is a cout or string operation involved or not. Moreover, the sample is different to that you posted above.

Regards, Alex
AxterCommented:
>>Yes, of course. But it would not compile because of "const_obj.SomeNonConstFunction()" regardless whether there is a cout

Yes, and that's the point.
I think you're letting cout be a distraction.  cout is not relevent, and it's only there as part of the over all example.
It could just as well been the following:
void SomeFunc(const foo &const_obj)
{
   const_obj.SomeNonConstFunction();//This WILL give you a compile error


>>What string operator are you referring to? Do you mean "ostream& operator<<(ostream&, const string&)" ?

Again, you're getting distract away from the main point.  Another example, with cout out of the picture.

void SomeFunc(const std::string &const_obj)
{
  int x = const_obj.size(); //This would give you a compile error **IF** the string::size did NOT have a const function


One of the main questions asked by the questioner was:
>>Does it add any value?

const adds value to a method, in that the method can be called if the object is a constant.
Objects are frequently of a constant type, when they're pass to a function in which the function does not modify the input argument.
void SomeFunc(const std::string &const_obj);
In this context, it's important that std::string members have constant types for non modifying methods.
If std::string didn't have const for it's methods, then you wouldn't be able to call any of std::string methods.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
itsmeandnobodyelseCommented:
>>>> it's important that std::string members have constant types for non modifying methods

We all are lucky that std::string is well defined regarding constness ;-)
Javaman59Author Commented:
Thankyou all. You have provided a thorough explanation of "const"ness. It will take me some time to work through all the details here, and when I do I'll post again.

For the moment, I've upgraded the question to 300 points (ie, 50 above "difficult"). It looks to me as if the responses have got into some arcane areas of C++, and have needed real expert attention.

I particularly thank you that you have addressed my question of "does it add any value?".

Javaman
Javaman59Author Commented:
Again, thankyou all.

I should have been more clear when I asked "does it add any value?". What I meant to say was that although it might be helpful to the programmer and compiler to know that a member function doesn't modify it's object, I can't really see that this, alone, justifies the use of the "const" modifier.

Axter hit the nail on the head by showing how "const" is not just "useful" but is *necessary* when the method is being applied to an object which is itself "const".

I thought the following contributions were helpful...

Danyd - correct explanation of the "const" modifier, and pointing out that the compiler may use it for optimisation.

Rajeev - bringing the "mutable" modifier to our attention (I never would have gone looking for it, it's so counter-intuitive!)

Alex - asking the right questions of Axter to get to the heart of the matter, and pointing out to us that "const" only applies to member functions.

Regards,

Javaman
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.