在 VS Code 中定义函数时对 vtable 的未定义引用 [duplicate]

Undefined reference to vtable when functions are defined in VS Code [duplicate]

提问人:equiv 提问时间:9/20/2021 最后编辑:equiv 更新时间:9/25/2021 访问量:402

问:

我看到了很多关于这个问题的问题,但似乎看不到我错过了什么。我对 C++ 相当陌生。我正在将 Visual Studio Code 与 G++ 和 MINGW32 10.3.0 一起使用。当我尝试运行 test.cpp(如下)时,我收到两个错误:

...test.cpp:7: undefined reference to 'QData::getDataPacket(void*)

...undefined reference to 'vtable for QData'

// qdata.h
#ifndef QDATA_H_
#define QDATA_H_

//Define generic queue data
class QData {
    private:
        int data = 17;                                                               
    public:
        void virtual getDataPacket(void* dataptr);                                 
        void virtual setDataPacket(void* dataptr);                                 
};

#endif
// qdata.cpp
#include "qdata.h"

void QData::getDataPacket(void* dataptr) {                                 
    *(int*)dataptr = data;                                                  
}

void QData::setDataPacket(void* dataptr) {                                 
    data = *(int*)dataptr;                                                  
}
// test.cpp
#include <iostream>
#include "qdata.h"

int main() {
    QData qqq;
    int a;
    qqq.getDataPacket(&a);
    std::cout << a << std::endl;

    return 0;
}

我知道代码有效,因为它最初都在一个文件中并且编译良好。根据我的研究,这可能是一个链接问题?与此相关的大多数问题都涉及需要定义您的虚拟功能,但我已经这样做了。

如果我在终端中使用以下命令,binary.exe 将正确运行(输出为 17):g++ -o binary test.cpp qdata.cpp

有没有办法让它正确编译和运行,而无需手动输入cpp文件列表?

编辑:由于似乎存在一些混淆,通常在 VSCode 中,您可以通过按 F5 一次性编译和调试。这是我收到上述错误的部分。我希望有人能帮助我理解为什么失败以及如何修复它,以便我可以继续在 VSCode 中测试/调试。

编辑:我仍然投票认为这个问题是独一无二的,因为我只是遵循 VS Code 中编译错误的跟踪。我之前实际上已经找到了这篇文章,但它并没有解决我的问题。它也非常密集,作为初学者很难理解它如何解释我的问题。我将添加一个 Visual Studio Code 标记来帮助人们找到这个问题。但是我发现的对 vtable 错误的所有其他引用都与 vtable 本身有关,而不是遵循 VS Code 中解决方案的故障排除路径。

C 可视化工作室代码 G++ 未定义引用 vtable

评论

0赞 Nicol Bolas 9/20/2021
"有没有办法让它正确编译和运行,而无需手动输入cpp文件列表?这听起来像是在问是否可以在不编译所有 C++ 程序的情况下编译 C++ 程序。不可以。“qdata.cpp”不是可选的。
0赞 equiv 9/20/2021
在 VSCode 中,只需按 F5 即可编译和运行调试器。当我这样做时,我得到了我提到的错误。我正在问如何让它使用 F5 进行编译和调试。
0赞 JaMiT 9/20/2021
这回答了你的问题吗?什么是未定义的引用/未解析的外部符号错误,如何解决?
0赞 JaMiT 9/20/2021
@equiv “我正在问如何让它用 F5 进行编译和调试。”您当前的问题 95% 集中在如何解决未定义的引用上。若要询问如何在 VS Code 中执行某些操作,应重新编写问题,使其侧重于如何在 VS Code 中使用多个 .ccp 源文件生成 c++ 程序。您可以跳过有关未定义引用和 vtable 的错误消息,因为您显然已经知道该解决方案。
0赞 equiv 9/20/2021
所以再说一遍,这里的初学者。请耐心等待。也许我不知道我在问什么?我不认为我是在问如何在 VSCode 中做某事,我是在解释当我按下 F5 并调用 g++ 进行编译(错误)时发生的事情与当我明确告诉它使用两个 cpp 文件时发生的情况是有区别的。我认为这些信息可能对有经验的人有帮助,帮助我了解如何解决我的问题。让它与 F5 一起工作是我的最终目标。我认为这是阻止它链接的编码错误。不是吗?我会看看你的链接。

答:

0赞 equiv 9/21/2021 #1

@JaMiT分享了一个链接,帮助我找到了答案。事实证明,代码很好,但问题在于如何在tasks.json文件中配置VisualStudio Code。如果你想用 g++ 编译多个 cpp 文件(假设你使用了 将 GCC 与 MINGW 一起使用入门指南),你需要修改 “args”。这是我的tasks.json,它指定要编译的cpp文件:

tasks.json

{
"tasks": [
    {
        "type": "cppbuild",
        "label": "C/C++: g++.exe build active file",
        "command": "C:\\msys64\\mingw64\\bin\\g++.exe",
        "args": [
            "-g",
            "test.cpp",
            "qdata.cpp",
            "-o",
            "${fileDirname}\\${fileBasenameNoExtension}.exe"
        ],
        "options": {
            "cwd": "${fileDirname}"
        },
        "problemMatcher": [
            "$gcc"
        ],
        "group": {
            "kind": "build",
            "isDefault": true
        },
        "detail": "Task generated by Debugger."
    }
],
"version": "2.0.0"

}

如果您只想编译 Active Directory 中的所有 cpp 文件,则可以按如下方式对其进行修改:

{
"tasks": [
    {
        "type": "cppbuild",
        "label": "C/C++: g++.exe build active file",
        "command": "C:\\msys64\\mingw64\\bin\\g++.exe",
        "args": [
            "-g",
            "*.cpp",
            "-o",
            "${fileDirname}\\${fileBasenameNoExtension}.exe"
        ],
        "options": {
            "cwd": "${fileDirname}"
        },
        "problemMatcher": [
            "$gcc"
        ],
        "group": {
            "kind": "build",
            "isDefault": true
        },
        "detail": "Task generated by Debugger."
    }
],
"version": "2.0.0"

}

请注意,它已从默认 tasks.json 文件的“args”中删除。"${file}"