• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 216
  • Last Modified:

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
0
Javaman59
Asked:
Javaman59
  • 3
  • 3
  • 2
  • +2
4 Solutions
 
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.
0
 
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
0
 
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.

0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
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


0
 
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
0
 
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
0
 
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.
0
 
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 ;-)
0
 
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
0
 
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
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

  • 3
  • 3
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now