Where are member functions stored for an object? - c++

I'm experimenting with C++ to understand how class/structures and their respective objects are laid out in memory and I understood that each field of a class/structure is an offset into their respective object (so I can have a member variable pointer).
I don't understand why, even if I can have member function pointers, the following code doesn't work:
struct mystruct
{
void function()
{
cout << "hello world";
}
int c;
};
int main()
{
unsigned int offset_from_start_structure = (unsigned int)(&((mystruct*)0)->c);
unsigned int offset_from_start_structure2 = (unsigned int)(&((mystruct*)0)->function); // ERROR - error C2276: '&' : illegal operation on bound member function expression
return 0;
}
My question is: why does the line
unsigned int offset_from_start_structure = (unsigned int)(&((mystruct*)0)->c);
compile and returns me the offset of the "c" field from the start of the structure and the line
unsigned int offset_from_start_structure2 = (unsigned int)(&((mystruct*)0)->function);
doesn't even compile?

Member functions or pointers to them aren't stored in the object. (virtual functions are typically called through a pointer stored in a table to which an object has a single pointer to) This would be a huge waste of memory. They're typically stored in a code memory section, and are known to the compiler. The object (*this) is typically passed as an invisible parameter so the functions know on which object to operate when they are called.
So, in layman terms, you'd have
0x10001000 void A::foo
.......... {code for A::foo}
and
push a;
call A::foo (0x10001000)
pop a;
where a is the object you're calling foo on.

Member function pointers are in practice not stored in objects: there's no need. The C++ standard doesn't specify exactly how e.g. virtual functions are to be implemented, but the common practice for virtual member functions is that each object contains a pointer to a table of function pointers; this pointer is called a vtable pointer.
You might try to get hold of “Inside the C++ object model” by Stanley Lippman.
Or, you might just try to get hold of my old pointers tutorial, which was once referenced from Wikipedia's pointers article, before my then homepage site disappeared.
Regarding the second question, why taking the address of p->memberFunc makes the compiler choke a little, well that expression has no type, it's just a syntactical entity, which you can apply an argument list to in order to call the function.
To wit,
struct S
{
void foo() {}
};
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
S* p = 0;
typeid( &p->foo );
}
Compilation:
[W:\dev\test]
> g++ foo.cpp
foo.cpp: In function 'int main()':
foo.cpp:12:17: error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say '&S::foo' [-fpermissive]
foo.cpp:12:22: warning: value computed is not used [-Wunused-value]
foo.cpp:12:22: warning: statement has no effect [-Wunused-value]
[W:\dev\test]
> _

Related

Is there any difference between Namespace::* and traditional *?

class C {
public:
int a;
int f();
};
int C::f() { return 0; }
int main() {
C c {1};
int(C::*pmf)() = &C::f;
// int(*pmf)() = &C::f; -> error can not convert int(*C::f)() to int(*f)().
}
Is there any difference between Namespace::* and * in ram or it is just checked by compiler? Is it syntactic sugar?
Of course: https://isocpp.org/wiki/faq/pointers-to-members
Non-static member functions have a hidden parameter that corresponds to the this pointer. The this pointer points to the instance data for the object.
The functions are physically not interchangable as members have an extra parameter - the object that you call it from. You cannot see it, but the compiler puts it in there. And when that object is missing, compiler obviously complains. This is not like C#, where every function is a member function, and some just happen to be static (fun fact: when passing a C# function to a third party, the object that it is attached to gets passed along with it to allow a valid call later. You may and may not be able to get away with emulating something similar here).

C++: Get address from member function pointer

I need am writing an operator== function that will need to compare two member function pointers and check to see if they point to the same function. I initially tried to do it like this:
typedef void(EventListenerClass::*EventHandler)(const Event&);
struct EventListener
{
EventListenerClass *_listener = NULL;
EventHandler _handler = NULL;
inline bool operator== (const EventListener& other) const
{ return addressof(_listener->*_handler) == addressof(other._listener->*_handler); };
};
But this gives me the following message:
Error: a pointer to a bound function may only be used to call the function
I found a potential solution here, which i will quote below:
In C++, pointer to member functions (PMFs) are implemented using a
wide pointer of sorts to handle all the possible call mechanisms; the
PMF needs to store information about how to adjust the ‘this’ pointer,
and if the function pointed to is virtual, where to find the vtable,
and where in the vtable to look for the member function. If you are
using PMFs in an inner loop, you should really reconsider that
decision. If that is not an option, you can extract the pointer to the
function that would be called for a given object/PMF pair and call it
directly inside the inner loop, to save a bit of time.
The syntax for this extension is
extern A a;
extern int (A::*fp)();
typedef int (*fptr)(A *);
fptr p = (fptr)(a.*fp);
I tried adapting this solution to my code as follows:
extern EventListenerClass a;
extern int (EventListenerClass::*fp)();
typedef int(*fptr)(EventListenerClass *);
fptr p = (fptr)(a.*fp);
But this just gave me the exact same error message as before. Can anyone tell me how i can compare these two member function pointers?

C++: How to call a member function pointer that is a member of the same class?

I'm trying to implement more flexibility in my numerics by allowing me to choose different forms of a mathematical function and vary their parameters through instantiating them as objects of a certain class. That class includes certain mathematical functions I may choose plus parameters that I can vary. The constructor of the class sets a member function pointer in the class to a member function according to what mathematical function I want. I want to solely use the pointer to call whatever function it points to by directly using the pointer in my routine.
However, that proved daunting as I didn't know that member function pointers require a certain syntax and seem to work somewhat differently from regular function pointers according to what I could gather. I've experimented quite a bit and constructed myself a minimal example shared below.
#include<iostream>
#include<string.h>
#include<cstdlib>
#include<stdio.h>
class Someclass
{
public:
// constructor to set pointer
Someclass(std::string);
// member function pointer to hold functions
void (Someclass::*fptr)();
// auxiliary function to call testfunction via pointer
void call ();
// testfunction
void foo();
};
// testfunction
void Someclass::foo()
{
printf("foo says hi! \n");
}
// call via specific function
void Someclass::call()
{
(this->*fptr)();
}
// constructor
Someclass::Someclass(std::string name)
{
if(name=="foo")
{
this->fptr = &Someclass::foo;
}
}
int main()
{
Someclass someobject("foo");
someobject.foo(); // direct testfunction call: Works OK
someobject.call(); // call via auxiliary function: Works OK
//(someobject.*fptr)(); // direct pointer dereferencing: Gives Error
return(EXIT_SUCCESS);
}
It shows that I can access the pointer by use of another member function that just calls whatever the pointer points to via use of a this pointer. However, I still can't seem to get the function call to work if I try to use the pointer directly in my main function through the line,
(someobject.*fptr)()
This particular expression leads to my compiler complaining about the scope and if I include the class scope, the compiler mentions invalid use of non-static members. Still, I'm confused as to why my implementation here doesn't work and if it does, how the proper syntax in my problem would be and why that has to be so.
Any insights would be really appreciated.
fptr is a member of the object, not a variable local to main. In such respect member function pointers behave exactly the same as all other variable types. You were so close, and just need to qualify the function pointer name with the object name:
(someobject.*(someobject.fptr))();
The reasons for this is .* indicates a pointer to member function and does not directly reference the members of an object like the . and .-> operators. Since fptr is a member of Someclass and not a local variable you need to reference it directly like so
(someobject.*someobject.fptr)();

Function Pointer - Compile time error

I am new to function pointers and I would like your help.
I am having a method:
int test3(int i)
{
return i;
}
Then in another method(not main) I do:
int (*pTest3)(int) = test3;
From the examples that I have read this seems ok.
However, I get a compile time error:
testFile.cpp:277:25: error: argument of type ‘int
({anonymous}::CheckingConsumer::)(int)’ does not match ‘int (*)(int)’
I do not understand what is wrong. Any help would be appreciated.
Thanks a lot.
Your test3 is a member function of a struct or a class. Class member functions have a hidden this parameter passed into them and so cannot be used with plain function pointers. You need to either declare the function as static or move it outside the struct/class, so that it no longer has a hidden this parameter, or use a class method pointer instead of a function pointer:
// static class method:
class X
{
static int test3(int i)
{
...
}
};
// Non-class method, at global scope
int test3(int i)
{
...
}
// Class method pointer
class X
{
int test3(int i)
{
...
}
};
// Create the method pointer
int (X::*pTest3) = &X::test3;
X *obj;
// Call the method pointer on an object
(obj ->* pTest3)(42);
Your method test3 seems to be an instance method. Later on you define pTest3 as function pointer, not as member function pointer.
Main difference between simple pointers and member pointers is that using the member pointer requires an instance of the object. An instance of the object tells what object should be processed and the value of the pointer tells what data field of the object should be used or what member function should be called. Value of the member pointer is conceptually equivalent to the offset from the beginning of the object to its member.
Declaring the member pointer using typedef:
typedef int (SomeClass::*MyMethodPtr)(int i);
MyMethodPtr ptr3 = SomeClass::test3;
Now using this pointer:
class SomeClass *pab = &ab;
int ret_value = (pab->*ptr3)(4);
Note that the instance of the class is used. There is other important point about the member pointers. They are implemented as structs that contain inside from 2 to 5 simple pointers and offsets depending on the compiler and other aspects like multiple inheritance, presence of vitrual base classes, etc.

c++ member function pointer problem

I'm new to c++ . I want to know about object pointer and pointer to member function . I wrote a code which is following:
code :
#include <iostream>
using namespace std;
class golu
{
int i;
public:
void man()
{
cout<<"\ntry to learn \n";
}
};
int main()
{
golu m, *n;
void golu:: *t =&golu::man(); //making pointer to member function
n=&m;//confused is it object pointer
n->*t();
}
but when i compile it it shows me two error which is following:
pcc.cpp: In function ‘int main()’:
pcc.cpp:15: error: cannot declare pointer to ‘void’ member
pcc.cpp:15: error: cannot call member function ‘void golu::man()’ without object
pcc.cpp:18: error: ‘t’ cannot be used as a function.
my question are following :
What I'm doing wrong in this code ?
How to make object pointer ?
How to make pointer to member function of a class and how to use them ?
Please explain me these concept.
Two errors corrected here:
int main()
{
golu m, *n;
void (golu::*t)() =&golu::man;
n=&m;
(n->*t)();
}
you want a pointer to function
the priority of the operators is not the one you expected, I had to add parenthesis. n->*t(); is interpreted as (n->*(t())) while you want (n->*t)();
A member function pointer has the following form:
R (C::*Name)(Args...)
Where R is the return type, C is the class type and Args... are any possible parameters to the function (or none).
With that knowledge, your pointer should look like this:
void (golu::*t)() = &golu::man;
Note the missing () after the member function. That would try to call the member function pointer you just got and thats not possible without an object.
Now, that gets much more readable with a simple typedef:
typedef void (golu::*golu_memfun)();
golu_memfun t = &golu::man;
Finally, you don't need a pointer to an object to use member functions, but you need parenthesis:
golu m;
typedef void (golu::*golu_memfun)();
golu_memfun t = &golu::man;
(m.*t)();
The parenthesis are important because the () operator (function call) has a higher priority (also called precedence) than the .* (and ->*) operator.
'void golu:: *t =&golu::man();' should be changed to 'void (golu:: *t)() =&golu::man;' you are trying to use pointer to function not pointer to result of a static function!
(1) Function pointer is not declared properly.
(2) You should declare like this:
void (golu::*t) () = &golu::man;
(3) Member function pointer should be used with object of the class.