Case I: Explaination of your 1st code snippet
When we write
void funcA();
this means funcA()
has a implicit parameter whose type is A *const
i.e., a const pointer to a non const A object. This in turn means we can call this function only on nonconst A objects. If you try to call this member function on a const A object you will get the mentioned error.
For showing my point lets try to call funcA
on a const A object. The code is as follows:
#include <iostream>
class A
{
public:
void funcA()
{
std::cout << "banana" << std::endl;
}
};
int main()
{
A nonconstobject;
nonconstobject.funcA(); //this works
const A constobject; //note the const here
constobject.funcA(); //this gives error: passing ‘const A’ as ‘this’ argument discards qualifiers
}
The above snippet gives the same error as you mentioned as can be seen here.
And this exactly what happens in your 1st code snippet. Now i am going to explain in steps what happens in your 1st code snippet:
Step 1. You have funcB();
declarared as const member function. Which means its own implicit parameter has type const B *const
i.e., a const pointer to const B object. This in turn means the data members(including data member t) of B are themselves const.
Step 2. Now since t
is const
and as i said in my custom example, you can't call a nonconst member function on a const object. So you get your mentioned error.
Case 2: Explaination of your 2nd code snippet
In the second case you have changed the data member t
to be of type A*
that is a pointer to A object.
Now lets look at in steps what happens in this case:
Step 1. You have funcB();
declarared as const member function. Which means its own implicit parameter has type const B *const
i.e., a const pointer to const B object. This in turn means the data members(including data member t) of B are themselves const. The difference this time is that t
will become a const pointer to A i.e., t
is of type A* const
Step 2. Again funcA
has implicit parameter that is of type A *const
since funcA
is not a const member function. And this type exactly matches with what you pass using the call t->funcA();
. So you don't get any error in this case.