如何解决具有绑定方法的程序已构建,但无法启动
考虑以下在C ++ 11下使用gcc编译的代码:
#include <cstdio>
#include <functional>
#include <unordered_map>
using namespace std;
using namespace std::placeholders;
class Box
{
char* box;
public:
Box(): box(new char[128]) {}
~Box()
{
delete[] this->box;
}
void example(int a,int b)
{
printf("%d %d",a,b);
}
};
Box box;
unordered_map<char,function<void(int,int)>> methods = {
{'a',bind(&Box::example,box,_1,8)}
};
int main()
{
fputs("Main called.",stdout);
return 0;
}
可以毫无错误地构建程序,但是尝试启动该程序将被忽略或导致失败。
在Windows 10上,即使程序应输出Main called.
,通过命令提示符启动生成的exe文件也只会打印没有说明的空白行。
在VS Code的集成终端中运行此命令时,我得到了更好的错误消息:
The terminal process "C:\WINDOWS\System32\cmd.exe /d /c {path to exe file} failed to launch (exit code: 3221226356).
当我将Box定义更改为不对Box成员使用指针的定义时,它会起作用:
class Box
{
char box[128];
public:
void example(int a,b);
}
};
有什么作用?
解决方法
这是C ++几个奥秘方面的结合:
unordered_map<char,function<void(int,int)>> methods = {
{'a',bind(&Box::example,box,_1,8)}
};
如果将其更改为:
unordered_map<char,&box,8)}
};
该代码仍应编译,并且可以正确运行。已通过gcc 10验证。
您的课程Box
violates the Rule Of Three。如果Box
对象被复制构造,将有一个具有相同指针的单个Box
对象的副本,并且当两个对象都被销毁时,将尝试对delete
同一指针多次。随后出现虚无。
所以这是引发您问题的第一个因素:您的课程不符合3规则。
第二个问题是std::bind
用途广泛,并且有多个重载。您在程序中使用的重载有效地归结为(作为其内部工作的一部分)制作了box
对象的内部副本,从而触发了Rule 3违规。
但是std::bind
在这里也可以通过bound方法使用指向对象的指针来工作,这样就无需复制它。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。