I'm asking you to help me understand this concept. Maybe I don't understand something, I don't know.. So I have this sample code:
#include <iostream>
class X{
int a;
public:
void do_lengthy_work();
};
void X::do_lengthy_work(){
std::cout << a << std::endl;
}
int main(){
X my_x;
printf("%p\n", &X::do_lengthy_work); // -> does compile
printf("%p\n", &my_x.do_lengthy_work); // -> doesn't compile,
// error: ISO C forbids taking the address of a bound member function to
// form a pointer to member function. Say &X::do_lengthy_work
}
I saw this sample of code in one book. I thought that we can't get an address of a class' method unless there's an object specified from which we want to get that function's address. But it turns out we can only get a class' method address, but not object's method address. I thought everytime we declare an object of a class, it gets it's own method, with separate address. Also if we do something like this:
#include <iostream>
class X{
int a;
public:
void do_lengthy_work();
int b;
};
void X::do_lengthy_work(){
std::cout << a << std::endl;
}
int main(){
X my_x;
printf("%p\n", &X::do_lengthy_work);
printf("%p\n",&X::b);
printf("%p",&my_x.b);
}
Example output is:
0x562446a9c17a
0x4
0x7ffe7491a4cc
Both class method's and object's variable address change. But the b's variable address does not change. It's always 0x4, 4 bytes further away from 0x00 because it's an int variable. But why it's address is so close to 0x00, but function's address is so further away? Also - repeating my question from previous code sample - why can't we get an address of a bound member function, but we can of a class' method?
So for example we can do this:
&X::method
but not this:
&object.method
I started thinking - can you correct me if I'm right? - variables from a class are initialized once when class is declared (thus we see an address of 0x4
when printing out an address of X::b), and then (uniquely) every other time we specify new object (thus we see 0x7ffe7491a4cc
when printing out an address of my_x.b), but methods are initialized only once and every object uses the same method which is always on the same address?
CodePudding user response:
You can basically think of X
as being implemented something like this:
struct X{
int a;
int b;
};
void X__do_lengthy_work(X* this);
Methods are pretty much the same as a normal function just with the addition of a hidden parameter of a pointer to the instance of the class.
Each instance of a class uses the same methods.
It could be misleading to take a pointer to a method for a particular instance as that might imply that you could call that method without having to provide the instance which is I guess why the language doesn't allow you to do that.