带向量的函数指针
Posted
技术标签:
【中文标题】带向量的函数指针【英文标题】:Function Pointer With Vector 【发布时间】:2020-07-29 10:36:06 【问题描述】:我是 C++ 新手。我正在尝试用 OpenGL 做可点击的按钮。我为每个按钮添加回调函数工作了 2 天,我尝试了很多我找到的方法,但我不能这样做。我下面的代码给出了内存错误。我的错在哪里?
main.h
#include <vector>
class Button
public:
// Storage Vector
static std::vector<Button> Buttons;
// typedef Function
typedef void (*pointerFunction)();
// Constructor
Button(/*Parameters*/);
// Setting Callback
void setCallBack(void(*function)());
// Callback pointer
pointerFunction callback;
int value 4 ;
;
main.cpp
#include <iostream>
#include "main.h"
std::vector<Button> Button::Buttons;
Button::Button(/*Parameters*/)
// ...
Button::Buttons.push_back(*this);
void Button::setCallBack(void(*function)())
this->callback = function;
this->callback(); // Here is work!
void testFunction()
std::cout << "Test\n";
void createMember()
Button classMember;
classMember.setCallBack(&testFunction);
int main()
createMember();
for (Button& button : Button::Buttons)
std::cout << button.value; // I can access this value.
button.callback(); // But here is give memory error!
return 0;
【问题讨论】:
请不要在问题中添加“问题已解决”。而是将解决您的问题的答案标记为已接受。 【参考方案1】:在这个函数中
void createMember()
Button classMember;
classMember.setCallBack(&testFunction);
有两件事正在做。第一个是创建本地对象classMember
。被调用的 construcfor 将对象的副本推送到向量 Buttons
内。副本的数据成员callback
未初始化。
.local 对象classMember
的数据成员callback
在其副本被推送到向量后被初始化。
重写函数至少像
void createMember()
Button classMember;
Button::Buttons.back().setCallBack(&testFunction);
如果未显式提供相应的初始化程序,则应特别使用文字 nullptr
初始化所有数据成员。在这种情况下,您将能够检查指针类型的数据成员是否等于nullptr
或存储实际值。
【讨论】:
【参考方案2】:您的 createMember
函数没有按预期工作。
void createMember()
Button classMember;
classMember.setCallBack(&testFunction);
创建一个将在函数退出时销毁的本地对象。
你可以这样做(虽然我认为这不是一个好的解决方案。)
Button & createMember()
static Button classMember;
classMember.setCallBack(&testFunction);
return classMemeber;
更好的解决方案:
std::vector<Button> Button::Buttons;
int main()
Button b;
for (Button& button : Button::Buttons)
button.setCallBack(testFunction);
std::cout << button.value; // I can access this value.
button.callback(); // But here is give memory error!
return 0;
请注意,您必须在某处玷污这在您的代码中是正确的,我忽略了它。Button::Buttons
,因为它是static
成员
而且,要添加至少一个Button
,您必须创建一个 以添加到vector
。
输出:
Test
4Test
您在setCallBack
和循环中调用了两次testFunction
。
(我添加了一个换行符。)
如果正如createMember
函数名所暗示的那样,你想调用它来创建每个新元素,你可以在构造函数中传递函数指针。如果它可以像您的示例一样简单地复制(类中没有指针或资源分配),您只需创建实例,vector
副本就可以了。
Button::Button(pointerFunction f) : callback (f)
// ...
Button::Buttons.push_back(*this);
void createMember()
Button classMember (testFunction);
int main()
createMember ();
for (Button& button : Button::Buttons)
std::cout << button.value; // I can access this value.
button.callback(); // But here is give memory error!
不过,我认为这对于任何真实事物来说都不是一个好的设计。
【讨论】:
【参考方案3】:你的错误是你创建了一个本地对象,把它的副本push到vector中,把回调地址放到原来的对象上,然后销毁原来的对象。好吧,你可以把回调地址作为构造函数参数,然后副本就有了。
// Constructor
Button(void(*function)(), /*Parameters*/) : callbackfunction
Button::Buttons.push_back(*this);
但我建议向 Button 类添加一个静态函数,该函数负责创建 Button 对象并返回对它的引用。这也消除了不必要的临时对象的创建/删除。
#include <iostream>
#include <vector>
class Button
public:
// Storage Vector
static std::vector<Button> Buttons;
// typedef Function
typedef void (*pointerFunction)();
// Constructor
Button(/*Parameters*/);
// Setting Callback
void setCallBack(void(*function)());
// Callback pointer
pointerFunction callback;
template<class... U>
static Button& createButton(U&&... u)
return Buttons.emplace_back(std::forward<U>(u)...);
int value 4 ;
;
std::vector<Button> Button::Buttons;
Button::Button(/*Parameters*/)
// ...
Button::Buttons.push_back(*this);
void Button::setCallBack(void(*function)())
this->callback = function;
this->callback(); // Here is work!
void testFunction()
std::cout << "Test\n";
void createMember()
auto &classMember = Button::createButton(/**/);
//Button classMember;
classMember.setCallBack(&testFunction);
int main()
createMember();
for (Button& button : Button::Buttons)
std::cout << button.value;
button.callback();
return 0;
【讨论】:
以上是关于带向量的函数指针的主要内容,如果未能解决你的问题,请参考以下文章