c++ - 使用绑定(bind)方法的程序已构建但无法启动

标签 c++ c++11 pointers

考虑使用 gcc 在 C++11 下编译的以下代码:

#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 上,通过命令提示符启动生成的 exe 文件只会打印一个没有解释的空行,即使程序应该输出 Main called. .
在 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, int b)
    {
        printf("%d %d", a, b);
    }
};
是什么赋予了?

最佳答案

这是 C++ 几个神秘方面的组合:

unordered_map<char, function<void(int, int)>> methods = {
    {'a', bind(&Box::example, box, _1, 8)}
};
如果您将其更改为:
unordered_map<char, function<void(int, int)>> methods = {
    {'a', bind(&Box::example, &box, _1, 8)}
};
代码应该仍然可以编译,并且可以正常运行。使用 gcc 10 验证。
您的类(class)Box violates the Rule Of Three .如果一个 Box对象被复制构造,将有单个 Box 的拷贝具有相同指针的对象,当它们都被销毁时,将尝试 delete同一个指针多次。希拉里随之而来。
所以这是引发您问题的第一个因素:您的类(class)不符合 Rule Of 3。
第二个问题是 std::bind非常通用,并且有多个重载。您在程序中使用的重载有效地归结为(作为其内部工作的一部分)box 的内部拷贝。对象被制造,触发违反规则 3。
但是std::bind也可以在这里使用指向具有绑定(bind)方法的对象的指针,这避免了复制它的需要。

关于c++ - 使用绑定(bind)方法的程序已构建但无法启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63947848/

相关文章:

c++ - 使用静态强制转换时,强制转换为类类型还是对象引用更有意义?

c++ - 如何识别部分模板特化

opencv - 确定数据类型并用作模板类型名

c - C中的字数统计,学习更多CS

c++ - i686-elf-gcc CreateProcess 错误(没有那个文件或目录)

c++ - ConvexPoly 不起作用后 OpenCV Canny

c++ - 从该对象的方法或另一个类构造函数中删除该对象是否被认为是不好的做法?

减少 CPU 指令大小的 C++ 技术?

c - *** 错误 : double free or corruption (out): 0x00007fffe3465010 ***. 警告 : Corrupted shared library list: 0x7ffea4000920 ! = 0x7ffff7ffd9d8

c - 将矩阵线保存到指针 C 中