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.
Related
I have two claces.
here is the first one
class one{
one(){ }
public:
void change(double a){
//print a
}
void run(){
two tw;
tw->functionpointer=&change;
}
};
and here is the two class
public two{
two();
static void progresschange(double v){
functionpointer(v);
}
public:
void (*functionpointer)(double);
};
as you see in example I have a function in class one, I want to call it from an static function in class two As progresschange is static I can only call change function in class one uisng function pointers. but It does not work and compiles says
error: cannot convert ‘void (one::*)(double)’ to ‘void (*)(double)’ in assignment
it happens in this line
tw->functionpointer=&change;
how can I make it work. it is even possible to pass a function using its function pointer to another class using this method?
thanks
The error message is quite straightforward:
error: cannot convert void (one::*)(double) to void (*)(double) in assignment
void one::change(double) is a member function of the class one, not just a function. Therefore, you can't assign a pointer to this member function (i.e.: void (one::*)(double)) to a pointer to a function with the same signature (i.e.: to a void (*)(double)).
Besides, a non-static member function (like one::change() above) has to be called on an object, so you also need to provide an one object to call that pointed-to non-static member function.
Basically, you can achieve what you want by adding the following data members in two:
void (one::*mem_func_ptr)(double);
one *obj_ptr;
That is, a pointer to the member function (mem_func_ptr) and a pointer to the object to call this member function on (obj_ptr).
To assign to the member function pointer:
mem_func_ptr = &one::change;
Then, to call the member function pointed by mem_func_ptr on the object pointed by obj_ptr with 0.0 as argument:
(obj_ptr->*mem_func_ptr)(0.0);
It can be done analogously by keeping a copy of an object one as data member instead of a ponter. In that case you should use the operator .* instead of ->*.
The problem is that one::change() is a class member so you need to pass a pointer to a class instance as well.
The modern way to do it is to use std::function, std::bind and std::mem_fn:
class two {
....
std::function<void(double)> functionpointer;
}
tw->functionpointer = std::bind(std::mem_fn(&one::change), _1, one_instance);
Alternatively you can use a lambda function:
tw->functionpointer = [&one_instance](double x) { one_instance->change(x); }
I need to use a function defined in one class in another class. Instead of rewriting the whole function, I tried to pass the function as a pointer, as below:
class C {
public:
int get(int x) { return x*x; }
};
struct S {
int (*func) (int x);
};
int main() {
C c;
S s;
cout << c.get(3) << endl;
s.func = &C::get;
cout << s.func(3) << endl;
return 0;
}
This doesn't work and gives the following error:
func_ptr.cpp: In function ‘int main()’:
func_ptr.cpp:42:18: error: cannot convert ‘int (C::*)(int)’ to ‘int (*)(int)’ in assignment
Is it possible to do something like this, and if so, how can I fix it? Moreover, if it is possible, can I use the pointer from an object instance instead of the class? That is, to possibly use variables defined in a specific class instance. Thanks.
C::get() is a non-static member function, which means it must be invoked on an instance of C. It has an implicit first argument, the this pointer, that must be passed to it when calling the function.
Since your C::get() doesn't seem to need access to any data members of C, you could make it a static member function.
static int get(int x) { return x*x; }
Now your code will work as is.
Another option is to change func so that it is a pointer to a member function of C
struct S {
int (C::*func) (int x);
};
And invoke it as
s.func = &C::get;
std::cout << (c.*(s.func))(3) << std::endl;
Yet another option would be to change the type of S::func to std::function<int(int)>. Now it can hold any callable (function pointer, functor, lambda) that takes a single int as an argument, and returns an int.
struct S {
std::function<int(int)> func;
};
s.func = std::bind(&C::get, &c, std::placeholders::_1);
std::cout << s.func(3) << std::endl;
A regular function and a member function are a bit different. To use a member function, you'll need an object to call it on (i.e. the this pointer in a member function body).
Take a look at std::function and std::bind, they are used to handle function like (callable) entities in a uniform way. They can manage global functions, static member functions, lambdas, regular member functions, functors, whatever that can be called like a function.
http://en.cppreference.com/w/cpp/utility/functional/function
http://en.cppreference.com/w/cpp/utility/functional/bind
http://en.cppreference.com/w/cpp/header/functional
e.g.:
struct S
{
std::function<int(int)> func;
};
C c;
S s;
s.func = std::bind( &C::get, &c, std::placeholders::_1 );
If you're OK with using STL then you can utilize std::function to hold a pointer to a function and std::bind to bind that particular pointer to a particular function. It makes your code look much more cleaner. std::bind looks for both static and non-static member functions. For non-static member function would need to pass the object reference so it will be able to point to the correct address.
Here is a code snippet to show how to use it:
std::bind(ClassName::MemberFunctionName, object, std::placeholders::_1)
std::placeholders::_1 means that ::MemberFunctionName accepts one parameter.
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]
> _
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.
Here is what I'd like to do. I have a function pointer which wants a function like this:
void func(int a);
so I have a class:
class Foo {
public:
void func(int a);
};
Foo *foo = new Foo;
something->setFunction(foo->func);
or in my case:
testWidget[count] = new TestWidget;
testWidget[count]->eventMouseClick.addHandler(testWidget[0]->silly);
But this gives me:
Error 5 error C3867:
'TestWidget::silly': function call
missing argument list; use
'&TestWidget::silly' to create a
pointer to
member c:\users\josh\documents\visual
studio
2008\projects\agui\alleg_5\main.cpp 190
Is there a way I could make this work without using a static function?
Thanks
Is there a way I could make this work without using a static function?
No. You can't convert a pointer to member function to an ordinary function pointer.
If the callback accepted any callable object (or a std::function, for example), then you could bind the object to the member function and pass the result of that; unfortunately, you can't convert that result to an ordinary function pointer, though.
Your question is not very clear to me. But the error message from the compiler makes me feel that probably you want something like this something->setFunction(&foo->func);
An example might help in case of overloads
struct T{
void func(int){}
void func(double){}
};
void f(void (T::*f)(int)){}
void f(void (T::*f)(double)){}
int main(){
void (T::*fi)(int) = &T::func;
void (T::*fd)(double) = &T::func;
f(fi);
f(fd);
}