I have a problem with using a pointer to function in C++. Here is my example:
我在使用C ++函数指针时遇到问题。这是我的例子:
#include <iostream>
using namespace std;
class bar
{
public:
void (*funcP)();
};
class foo
{
public:
bar myBar;
void hello(){cout << "hello" << endl;};
};
void byebye()
{
cout << "bye" << endl;
}
int main()
{
foo testFoo;
testFoo.myBar.funcP = &byebye; //OK
testFoo.myBar.funcP = &testFoo.hello; //ERROR
return 0;
}
Compilator returns an error at testFoo.myBar.funcP = &testFoo.hello;
:
Compilator在testFoo.myBar.funcP =&testFoo.hello;上返回错误:
ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say '&foo::hello'
ISO C ++禁止获取绑定成员函数的地址以形成指向成员函数的指针。说'&foo :: hello'
cannot convert 'void (foo::)()' to 'void ()()' in assignment
无法在赋值时将'void(foo ::)()'转换为'void()()'
So i tried it like this:
所以我试着这样:
class bar
{
public:
void (*foo::funcP)();
};
But now the compilator adds one more:
但是现在编译器增加了一个:
'foo' has not been declared
'foo'尚未宣布
Is there a way make it work?
有没有办法让它发挥作用?
Thanks in advance for suggestions
提前感谢您的建议
4 个解决方案
#1
13
Taking everyone's suggestions together, your final solution will look like:
将每个人的建议放在一起,您的最终解决方案将如下所示:
#include <iostream>
using std::cout;
usind std::endl;
class foo; // tell the compiler there's a foo out there.
class bar
{
public:
// If you want to store a pointer to each type of function you'll
// need two different pointers here:
void (*freeFunctionPointer)();
void (foo::*memberFunctionPointer)();
};
class foo
{
public:
bar myBar;
void hello(){ cout << "hello" << endl; }
};
void byebye()
{
cout << "bye" << endl;
}
int main()
{
foo testFoo;
testFoo.myBar.freeFunctionPointer = &byebye;
testFoo.myBar.memberFunctionPointer = &foo::hello;
((testFoo).*(testFoo.myBar.memberFunctionPointer))(); // calls foo::hello()
testFoo.myBar.freeFunctionPointer(); // calls byebye()
return 0;
}
The C++ FAQ Lite has some guidance on how to simplify the syntax.
C ++ FAQ Lite有关如何简化语法的一些指导。
Taking Chris' idea and running with it, you could get yourself something like this:
采取克里斯的想法并运行它,你可以得到这样的事情:
#include <iostream>
using std::cout; using std::endl;
class foo;
typedef void (*FreeFn)();
typedef void (foo::*MemberFn)();
class bar
{
public:
bar() : freeFn(NULL), memberFn(NULL) {}
void operator()(foo* other)
{
if (freeFn != NULL) { freeFn(); }
else if (memberFn != NULL) { ((other)->*(memberFn))(); }
else { cout << "No function attached!" << endl; }
}
void setFreeFn(FreeFn value) { freeFn = value; memberFn = NULL; }
void setMemberFn(MemberFn value) { memberFn = value; freeFn = NULL; }
private:
FreeFn freeFn;
MemberFn memberFn;
};
class foo
{
public:
bar myBar;
void hello() { cout << "foo::hello()" << endl; }
void operator()() { myBar(this); }
};
void bye() { cout << "bye()" << endl; }
int main()
{
foo testFoo;
testFoo();
testFoo.myBar.setMemberFn(&foo::hello);
testFoo();
testFoo.myBar.setFreeFn(&bye);
testFoo();
return 0;
}
#2
7
As the error says, methods belong to the class, not to individual instances. For this reason pointers to free functions and pointers to non-static methods are completely different things. You'll also need an instance to call the method on.
正如错误所说,方法属于类,而不属于单个实例。因此,指向*函数和指向非静态方法的指针是完全不同的事情。您还需要一个实例来调用该方法。
//declaring and taking the address of a foo's method
void (foo::*method)() = &foo::hello; //as the compiler nicely suggests
//calling a function through pointer
free_func();
//calling a method through pointer
foo instance;
(instance.*method)();
You can use libraries like Boost.Bind and Boost.Function (also in std::tr1 I think) to abstract away the difference and also bind an instance to the method:
您可以使用像Boost.Bind和Boost.Function这样的库(我认为也是在std :: tr1中)来抽象差异并将实例绑定到方法:
#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
using namespace std;
class foo
{
public:
void hello(){cout << "hello" << endl;};
};
void byebye()
{
cout << "bye" << endl;
}
int main()
{
foo testFoo;
boost::function<void()> helloFunc(boost::bind(&foo::hello, testFoo));
boost::function<void()> byeFunc(byebye);
helloFunc();
byeFunc();
return 0;
}
#3
0
To make your second option work, declare foo so the compiler knows that it is a class.
要使第二个选项有效,请声明foo,以便编译器知道它是一个类。
Also note that your function pointer syntax is incorrect. The *
comes just before the name of the variable:
另请注意,函数指针语法不正确。 *出现在变量名称之前:
class foo;
class bar
{
public:
void (foo::*funcP)();
};
#4
0
forward foo's declaration in front of bar:
前锋foo在酒吧前面的声明:
class foo;
#1
13
Taking everyone's suggestions together, your final solution will look like:
将每个人的建议放在一起,您的最终解决方案将如下所示:
#include <iostream>
using std::cout;
usind std::endl;
class foo; // tell the compiler there's a foo out there.
class bar
{
public:
// If you want to store a pointer to each type of function you'll
// need two different pointers here:
void (*freeFunctionPointer)();
void (foo::*memberFunctionPointer)();
};
class foo
{
public:
bar myBar;
void hello(){ cout << "hello" << endl; }
};
void byebye()
{
cout << "bye" << endl;
}
int main()
{
foo testFoo;
testFoo.myBar.freeFunctionPointer = &byebye;
testFoo.myBar.memberFunctionPointer = &foo::hello;
((testFoo).*(testFoo.myBar.memberFunctionPointer))(); // calls foo::hello()
testFoo.myBar.freeFunctionPointer(); // calls byebye()
return 0;
}
The C++ FAQ Lite has some guidance on how to simplify the syntax.
C ++ FAQ Lite有关如何简化语法的一些指导。
Taking Chris' idea and running with it, you could get yourself something like this:
采取克里斯的想法并运行它,你可以得到这样的事情:
#include <iostream>
using std::cout; using std::endl;
class foo;
typedef void (*FreeFn)();
typedef void (foo::*MemberFn)();
class bar
{
public:
bar() : freeFn(NULL), memberFn(NULL) {}
void operator()(foo* other)
{
if (freeFn != NULL) { freeFn(); }
else if (memberFn != NULL) { ((other)->*(memberFn))(); }
else { cout << "No function attached!" << endl; }
}
void setFreeFn(FreeFn value) { freeFn = value; memberFn = NULL; }
void setMemberFn(MemberFn value) { memberFn = value; freeFn = NULL; }
private:
FreeFn freeFn;
MemberFn memberFn;
};
class foo
{
public:
bar myBar;
void hello() { cout << "foo::hello()" << endl; }
void operator()() { myBar(this); }
};
void bye() { cout << "bye()" << endl; }
int main()
{
foo testFoo;
testFoo();
testFoo.myBar.setMemberFn(&foo::hello);
testFoo();
testFoo.myBar.setFreeFn(&bye);
testFoo();
return 0;
}
#2
7
As the error says, methods belong to the class, not to individual instances. For this reason pointers to free functions and pointers to non-static methods are completely different things. You'll also need an instance to call the method on.
正如错误所说,方法属于类,而不属于单个实例。因此,指向*函数和指向非静态方法的指针是完全不同的事情。您还需要一个实例来调用该方法。
//declaring and taking the address of a foo's method
void (foo::*method)() = &foo::hello; //as the compiler nicely suggests
//calling a function through pointer
free_func();
//calling a method through pointer
foo instance;
(instance.*method)();
You can use libraries like Boost.Bind and Boost.Function (also in std::tr1 I think) to abstract away the difference and also bind an instance to the method:
您可以使用像Boost.Bind和Boost.Function这样的库(我认为也是在std :: tr1中)来抽象差异并将实例绑定到方法:
#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
using namespace std;
class foo
{
public:
void hello(){cout << "hello" << endl;};
};
void byebye()
{
cout << "bye" << endl;
}
int main()
{
foo testFoo;
boost::function<void()> helloFunc(boost::bind(&foo::hello, testFoo));
boost::function<void()> byeFunc(byebye);
helloFunc();
byeFunc();
return 0;
}
#3
0
To make your second option work, declare foo so the compiler knows that it is a class.
要使第二个选项有效,请声明foo,以便编译器知道它是一个类。
Also note that your function pointer syntax is incorrect. The *
comes just before the name of the variable:
另请注意,函数指针语法不正确。 *出现在变量名称之前:
class foo;
class bar
{
public:
void (foo::*funcP)();
};
#4
0
forward foo's declaration in front of bar:
前锋foo在酒吧前面的声明:
class foo;