Reputation: 3995
While reading about *this
, I saw:
When a nonstatic member function is called for an object, the compiler passes the object's address to the function as a hidden argument.
Then I tried:
#include <iostream>
class MyClass
{
int myVar;
public:
MyClass(const int& val) : myVar{val} {}
// int getVar(MyClass* this) <-- Error: expected ',' or '...' before 'this'
int getVar()
{
return this->myVar;
}
};
int main()
{
MyClass obj(22);
// std::cout << obj.getVar(&obj); <-- Error: no matching function
// std::cout << MyClass::getVar(&obj); <-- Error: no matching function
std::cout << obj.getVar();
return 0;
}
Why am I not able to access the hidden argument? Is it called 'hidden' because of that?
Are only compilers allowed to do this? Can't we explicitly mention *this
in the function signature?
The closest answer I've found before asking this is this. But I tried that way and still got the error. Could I get an explanation of those error messages? Because, if the compiler actually modifies those function signatures to contain *this
then that should have worked, isn't it?
Upvotes: 1
Views: 1976
Reputation: 2160
When you are doing obj.getVar() it is already explicitly specified the pointer this=&obj and passed implicitly to getVar. It is not hidden. It is explicitly passed leftside of the function. You can use obj.getVar() or ptrObj->getVar() but in C++ is not allowed to use such construction getVar(thisptr). Hidden means the variable named this is nowhere declared, but you can use inside the function.
Upvotes: 2
Reputation: 40604
Are only compilers allowed to do this?
Precisely. That's why it's called hidden: It's something that the compiler does on your behalf, but which is hidden from the C++ code that uses it.
The compiler must pass the this
pointer to the member function somehow, but it does not need to tell you how it does it. It could compile the code to the equivalent of MyClass::getVar(&obj)
, passing the this
pointer in the same way that it would pass the argument for the C function free(foo)
. Or it might use a different mechanism that is totally incompatible with non-member argument passing. What it does under the hood is defined by the platform's Abstract Binary Interface standard (ABI), which is not part of the C++ language standard. What happens under Windows could be vastly different from what happens under Linux, and Linux on ARM could be different from Linux on X86, etc.
That said, you can take a look at what actually happens by telling your compiler to produce the assembly code. For gcc
, the incantation would be
g++ -S -Os interestingCode.cpp
This will produce a .s
file that contains how g++
actually translated your code.
Upvotes: 3
Reputation: 9602
obj.getVar(&obj)
This version cannot compile because the getVar()
member function is not declared to take any parameters.
MyClass::getVar(&obj)
This version is using the syntax to access a static
function but getVar()
is not static
, nor does it accept any parameters.
Note: The obj.getVar()
call works because it is specifying which object instance to use (i.e., the obj.
part) to execute the member function and is conceptually how the member function is passed the this
pointer.
Upvotes: 2