我有一个带有按钮的消息框类,点击后执行给定的功能:
// cMessage.h
#include "cButton.h"
class cMessage{
public:
std::vector<cButton*> button;
cMessage(const std::vector<std::function<void()> >& effect);
~cMessage();
void alert();};
// cMessage.cpp
cMessage::cMessage(const std::vector<std::function<void()> >& effect){
for(unsigned int i = 0; i < effect.size(); i++)
button.push_back(new cButton(effect[i], this)); }
cMessage::~cMessage(){
for(unsigned int i = 0; i < button.size(); i++)
delete button[i];}
void cMessage::alert(){
delete this;}
// cButton.h
class cMessage;
class cButton{
private:
cMessage* alert;
const std::function<void()> effect;
public:
cButton(const std::function<void()>& effect, cMessage* alert);
void onClick();}
// cButton.cpp
cButton::cButton(const std::function<void()>& effect, cMessage* alert): effect(effect), alert(alert){}
void cButton::onClick(){
if(alert) alert->alert();
if(effect) effect();}
当我传递一个lambda函数时会出现问题,因为当我让lambda函数捕获一个由字符串和unsigned int组成的对时,该字符串在执行函数时是空的。但是,unsigned int仍然是1。
// main.cpp
#include "cMessage.h"
int main(){
cMessage* message;
{const pair<const string, const unsigned int> var("test", 1);
std::function<void()> f = [var](){ std::cout << var.first << std::endl << var.second << std::endl; } };
message = new cMessage( {f} );}
message->button[0]->onClick();
return 0;}
对于一些更多的couts,我发现在cButton的构造函数中,字符串仍然是&#34; test&#34;。 使它更奇怪的是,当我直接构造一个按钮时,问题不会发生。
解决了问题 它是由未定义的行为引起的,因为在删除按钮后调用了lambda函数(该按钮在它之前调用了它的消息导致它被删除)。这也解释了为什么直接创建按钮不会给出问题。让我感到惊讶的是,我还没有遇到任何其他问题。谢谢你的帮助
答案 0 :(得分:0)
我建议重新思考
new cButton(this, effect[i]);
否则分享更多代码。
---编辑---
您粘贴的代码appears to produce the right output:
#include <iostream>
#include <vector>
#include <string>
#include <functional>
#include <utility>
class cButton{
private:
const std::function<void()> effect;
public:
cButton(const std::function<void()>& effect);
void onClick();};
cButton::cButton(const std::function<void()>& effect): effect(effect){}
class cMessage{
public:
std::vector<cButton*> button;
cMessage(const std::vector<std::function<void()> >& effect);};
cMessage::cMessage(const std::vector<std::function<void()> >& effect){
for(unsigned int i = 0; i < effect.size(); i++)
button.push_back(new cButton(effect[i])); }
void cButton::onClick(){
if(effect) effect();
}
int main(){
cMessage* message{};
{
const std::pair<const std::string, const unsigned int> var("test", 1);
std::function<void()> f = [var](){ std::cout << var.first << std::endl << var.second << std::endl; };
message = new cMessage( {f} );
}
message->button[0]->onClick();
}
Output:
test
1