5

I couldn't understand the reason for not allowing modifiers such as const or volatile to nonmembers functions.

Following is the example code I tired

class A
{
private:
    int var;
public:
    int func();
};

int A::func()
{
    // Some calculation on using var
    int temp = var + 10;
    return temp;
}

void func2( const A& tempObj ) const;

void func2( const A& tempObj ) 
{
    std::cout << "temp obj called : " << tempObj.func() << std::endl;
}

int main()
{
    A aobj;
    aobj.func();
    func2( aobj );
    return 0;
}

which throws an compiler error error C2270: 'func2' : modifiers not allowed on nonmember functions for void func2( const A& tempObj ) const;

I also get another error error C2662: 'A::func' : cannot convert 'this' pointer from 'const A' to 'A &' for tempObj.func() in func2 here I was assuming that the member function func will be called without any errors.

Krishna Oza
  • 1,390
  • 2
  • 25
  • 50

4 Answers4

15

const modifier states that a member function won't modify data members of the object the function belongs to.

It's like an assurance that calling that function on an object aobj won't modify the internal state of that object. So, assuming that aobj is declared const too, you will still be able to invoke that function on it; on the contrary, you would not be able to invoke non const function members.

If a function is not member of a class, it makes no sense to apply const modifier. On another language, it could have meant that the function wasn't able to modify global variables, maybe; but that language is not C++.

Paolo M
  • 12,403
  • 6
  • 52
  • 73
5

Imagine that there is a hidden parameter on each non-static member function:

int A::func(A* this) {...}

If you declare a member function const or volatile, that is added to that hidden parameter, pretty much like the following:

int A::func(const A* this) {...}

Some languages like python make the instance parameter on the member functions explicit, so there you write def func(self): inside a class definition to declare non-static functions.

wigy
  • 2,174
  • 19
  • 32
3

In C++, the member function modifiers apply to the object on which the function is being called. That is the use the language has for these modifiers.

Non-member functions have no such object, so the qualification would make no sense. One could imagine the language allowing cv-qualifying non-members as having no effect, but in my mind this would only be confusing. One could also imagine the cv-qualifiers having a different meaning for non-members, but the reality is what it is. That is the way the language was designed.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • still, `const` on non-members could mean something like "doesn't change global variables" or so, see also http://stackoverflow.com/questions/14127379/does-const-mean-thread-safe-in-c11 – davidhigh Mar 18 '15 at 07:41
  • @davidhigh Right, but the answer to "Why modifiers like const not allowed on nonmember functions" is because the modifiers apply to the object, not to anything else. – juanchopanza Mar 18 '15 at 07:43
  • 2
    @davidhigh, Realistically, that restriction would appear as part of "pure", which has been proposed and at least GCC has an attribute for. – chris Mar 18 '15 at 07:44
  • @juanchopanza: sure, I was not criticizing your answer, but rather extending the question. – davidhigh Mar 18 '15 at 07:45
  • @davidhigh It is a good point though. In the end, it is a language design decision. – juanchopanza Mar 18 '15 at 07:51
  • @juanchopanza I think the explanation for not allowing `const` to member function fairly answer my question but could you help me understand why with `const` removed from `func2` declaration I am getting error or unable to call `tempObj.func()` from `func2`. – Krishna Oza Mar 18 '15 at 07:52
  • 1
    @Krishna_Oza `A::func()` is not a `const` member function, so it can't be called via a `const` reference. – juanchopanza Mar 18 '15 at 07:53
  • @juanchopanza I agree to you and completely understand your point but isn't the error message `cannot convert 'this' pointer from 'const A' to 'A &` should be saying `cannot convert this pointer from const A& to const A`. Or since the `this` pointer itself is a `cosnt *`. – Krishna Oza Mar 18 '15 at 08:01
  • 1
    @Krishna_Oza No. The "this" pointer in your case is the `tempObj`, that is, a `const A`. But you're trying to call a non-`const` function on it, which requires an `A&` for its "this". So it's a conversion from `const A&` to `A&` which fails. – Angew is no longer proud of SO Mar 18 '15 at 08:13
3

A const qualification on a class method declares that the method doesn't modify any (non-mutable) member variables.

It therefore just doesn't make any sense to declare that on a non-member function because there are no member variables for it to modify.

The const qualification is very useful because it explicitly indicates that it's safe to call this method on a const variable without breaching the constness of that variable.

Alnitak
  • 334,560
  • 70
  • 407
  • 495