C++ 从函数定义在 main 中的类中的函数指针向量调用函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15128444/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ calling a function from a vector of function pointers inside a class where the function definition is in main
提问by Steven Venham
Alright, in my main i have:
好吧,在我的主要我有:
void somefunction();
int main()
{
//bla bla bla
SomeClass myclass = SomeClass();
void(*pointerfunc)() = somefunction;
myclass.addThingy(pointerfunc);
//then later i do
myclass.actionWithDiffrentOutcomes();
}
void somefunction()
{
//some code
}
and in the class:
在课堂上:
class SomeClass()
{
public:
void addThingy(void (*function)());
void actionWithDiffrentOutcomes();
private:
std::vector<void (**)()> vectoroffunctions;
}
SomeClass::addThingy(void (*function)())
{
vectoroffunctions.push_back(&function);
}
SomeClass::actionWithDiffrentOutcomes()
{
(*vectoroffunctions[0])();;
}
I'm sort of new-ish to pointers, but I read over my c++ books, googled, ext. and this seems correct, compiles, runs but when I call "actionWithDiffrentOutcomes()" I get an access violation. I'm not sure what to do. it seems correct, but something is obviously wrong. So how can I call a function from within a class when the definition is in another?
我对指针有点陌生,但我阅读了我的 C++ 书籍,谷歌搜索,ext。这似乎是正确的,编译,运行,但是当我调用“actionWithDiffrentOutcomes()”时,我遇到了访问冲突。我不知道该怎么做。这似乎是正确的,但显然有些错误。那么当定义在另一个类中时,如何从类中调用函数?
I'm doing it this way because i cannot hard-code every option into a switch statement.
我这样做是因为我无法将每个选项硬编码到 switch 语句中。
回答by Mankarse
Your code is almost correct. Your vector is mistakenly holding pointers to pointers to functions rather than simply pointers to functions. addThingy
is adding the address of the function
pointer in to the vector
, but that pointer goes out of scope in the next line.
你的代码几乎是正确的。您的向量错误地持有指向函数指针的指针,而不仅仅是指向函数的指针。addThingy
正在将function
指针的地址添加到 中vector
,但该指针在下一行中超出范围。
Change your code as follows:
更改您的代码如下:
//Store pointers to functions, rather than
//pointers to pointers to functions
std::vector<void (*)()> vectoroffunctions;
SomeClass::addThingy(void (*function)())
{
//Don't take the address of the address:
vectoroffunctions.push_back(function);
}
Also, you have a lot of syntax errors in the rest of the code which should stop the code from even compiling.
此外,您在其余代码中有很多语法错误,这应该会阻止代码甚至编译。
回答by Nawaz
The problem is here:
问题在这里:
vectoroffunctions.push_back(&function);
You're adding address of the localvariable. The local variable gets destroyed once you return from the function. The address which the vector stores points to a destroyed object which is why you get "access violation"error at runtime.
您正在添加局部变量的地址。一旦从函数返回,局部变量就会被销毁。向量存储的地址指向一个被破坏的对象,这就是为什么在运行时会出现“访问冲突”错误的原因。
To fix this, do this:
要解决此问题,请执行以下操作:
First change this
先改这个
std::vector<void (**)()> vectoroffunctions;
to this:
对此:
std::vector<void (*)()> _functions; //vector of function-pointer-type
//I changed the name also!
which is practically same as:
这实际上与以下内容相同:
std::vector<void()> _functions; //vector of function-type
Now do this:
现在这样做:
_functions.push_back(function); //add copy!
To make it more flexible, you could use template along with std::function
as:
为了使其更灵活,您可以将模板与std::function
as一起使用:
class A
{
public:
template<typename Function>
void add(Function && fn)
{
_functions.push_back(std::forward<Function>(fn));
}
void invoke_all()
{
for(auto && fn : _functions)
fn();
}
private:
std::vector<std::function<void()>> _functions;
};
Now you can use it to store functions as well as functors:
现在您可以使用它来存储函数和函子:
void myfunction() { std::cout << "myfunction" << std::endl ; }
struct myfunctor
{
void operator()() { std::cout << "myfunctor" << std::endl ; }
};
A a;
a.add(myfunction); //add function
a.add(myfunctor()); //add functor!
a.invoke_all();
Output (Online Demo):
输出(在线演示):
myfunction
myfunctor
Hope that helps.
希望有帮助。
回答by Johnsyweb
Function pointers are much more legible with typedefs
:
函数指针更清晰typedefs
:
typedef void (*RequiredFunction)();
Then you can declare addThingy()
like this:
然后你可以这样声明addThingy()
:
void addThingy(RequiredFunction function);
And vectoroffunctions
like so:
而vectoroffunctions
像这样:
std::vector<RequiredFunction> vectoroffunctions;
The definition of addThingy
will be:
addThingy
will的定义是:
void SomeClass::addThingy(RequiredFunction function)
{
vectoroffunctions.push_back(function);
}
And your main()
would look more like:
你main()
看起来更像:
int main()
{
SomeClass sc;
RequiredFunction pointerfunc = somefunction;
sc.addThingy(pointerfunc);
sc.actionWithDiffrentOutcomes();
}
Far fewer *
s and &
s with which to make mistakes!
少得多的*
s 和&
s 犯错误!