VC++常见错误原因解析--error LNK2019: 无法解析的外部符号 "public: void __thiscall

本文详细阐述了在C++开发过程中遇到'符号无法解析'错误时可能出现的原因,并提供了针对性的解决策略。主要分为五个方面:未实现方法、文件未添加至项目目录、文件名冲突、内联函数相关问题和动态库未包含。通过理解这些原因,开发者能够快速定位问题并修复错误。

出现这个错误,应该首先查看“#include”语句是否包含,或者是否包含正确。符号无法解析意味着编译器知道有这个符号存在,也就是有声明,但在链接时,找不到实现代码,那么就去看看报错的这个函数有没有实现代码。如果它们的确已经有了,还是出现这个错误,就把它们重新编译一下。

根据个人遇到这个错误时的记录,原因可以分为一下几种:

原因一:只是在.h里面声明了某个方法,没有在cpp里面实现
具体讲,有时候在头文件中声明了需要的方法,确实忘记了在源文件中实现;
有时候在头文件中声明了需要的方法,在源文件中实现了该方法,但是却遗留了方法名前的“classname::”;
有时候在头文件中声明并实现了需要的方法,但是在代码调整时直接把方法copy到源文件时,并没有在函数前加“classname::”;


原因二:声明和实现都有了,但是没有添加到vs的project目录下面,这时候如果在其他.cpp中引用的,就会出现这个错误。
具体讲,导入自己以前的代码或其他现有代码时,复制到工程下目标文件夹后,有时候会在vs的project目录下忘记或遗漏添加这些文件,就可能引起这个错误。


原因三:有时候工程比较大时,会直接加入一些原有的基础工程来提交效率,如果对原有工程不太熟悉,在工程中加入了有相同名字的文件或者类时,同样会引起这个问题。
这种情况下的具体原因是编译时会出现相同名字的中间文件,因为编译有先后顺序,出现了文件替换,在其他文件引用被替换掉的文件时,导致最后会出现了个连接问题。


原因四:内联函数相关,如果内联函数的声明在头文件中,实现在源文件中,这时候如果其他类中只是包含了头文件,在调用这个内联函数时也会出现这个问题。此时把函数实现放到头文件中,或者把.cpp也include进来,就可以解决问题。


原因五:如果这个类是动态库中定义的类,可能是因为没有把这个动态库对应的.lib文件加到工程中。


原文地址:http://blog.youkuaiyun.com/tobefxz/article/details/22154469

这个错误: ``` LNK2019: 无法解析外部符号 "public: void __thiscall EightMyPlan::updateAllButtonsLayout(void)" ``` 说明编译器在链接阶段找不到 `EightMyPlan::updateAllButtonsLayout()` 这个函数的实现。 --- ### 🔍 错误原因分析 你**声明了**一个成员函数: ```cpp // 在 EightMyPlan.h 中 class EightMyPlan : public QWidget { Q_OBJECT public: void updateAllButtonsLayout(); // 声明了,但没有定义(实现) }; ``` 但是你**没有提供它的实现(即函数体)**,或者实现了但文件没被编译进去。 链接器在编译 `MainWindow::CreateScrollArea` 时发现调用了 `eightMyPlanInstance->updateAllButtonsLayout();`,但它在所有目标文件中都找不到该函数的实际代码,于是报错 `LNK2019` —— **未解析外部符号**。 --- ### ✅ 解决方法 #### ✔ 步骤 1:确认函数已实现 你需要在 `.cpp` 文件中实现这个函数。例如: ```cpp // eightmyplan.cpp #include "eightmyplan.h" void EightMyPlan::updateAllButtonsLayout() { // 实现你的逻辑,比如更新按钮样式、布局等 for (QPushButton* btn : buttonList) { // 假设你有一个成员变量 QList<QPushButton*> buttonList; if (btn) { btn->setStyleSheet("QPushButton { background-color: red; color: white; }"); btn->setFixedSize(100, 40); } } } ``` > 注意:如果你的函数参数是 `QList<QPushButton*>`,那应该是: > ```cpp > void EightMyPlan::updateAllButtonsLayout(QList<QPushButton*> btnList) > ``` 请确保**声明和定义的签名完全一致**。 --- #### ✔ 步骤 2:确保 .cpp 文件已加入项目(让编译器编译它) 检查你的 `.pro` 文件是否包含: ```qmake SOURCES += \ eightmyplan.cpp \ mainwindow.cpp \ main.cpp HEADERS += \ eightmyplan.h \ mainwindow.h ``` 如果 `eightmyplan.cpp` 没有加进 `SOURCES`,它就不会被编译,导致函数缺失。 > 📌 Qt Creator 小技巧:右键项目 → “添加现有文件” 把 `.cpp` 和 `.h` 都加进去。 --- #### ✔ 步骤 3:清理并重新构建项目 有时旧的目标文件会缓存错误状态。 执行以下操作: 1. **Build → Clean All** 2. **Build → Rebuild All** 或手动删除 `build-*` 目录后重新 qmake 构建。 --- #### ❌ 常见错误写法举例 ```cpp // 只在头文件里写实现,但没在类外定义(容易遗漏) class EightMyPlan : public QWidget { void updateAllButtonsLayout() {} // 内联实现可以,但如果没写{}还是不行! }; ``` 如果你只是声明而没实现,即使写了 `{}` 也要确保语法正确。 --- ### ✅ 正确结构示例 #### eightmyplan.h ```cpp #ifndef EIGHTMYPLAN_H #define EIGHTMYPLAN_H #include <QWidget> #include <QList> #include <QPushButton> class EightMyPlan : public QWidget { Q_OBJECT public: explicit EightMyPlan(QWidget *parent = nullptr); void updateAllButtonsLayout(); // 声明 // 或者带参数版本: // void updateAllButtonsLayout(QList<QPushButton*> btnList); private: QList<QPushButton*> buttonList; // 示例成员 }; #endif // EIGHTMYPLAN_H ``` #### eightmyplan.cpp ```cpp #include "eightmyplan.h" EightMyPlan::EightMyPlan(QWidget *parent) : QWidget(parent) { // 初始化按钮列表 buttonList << new QPushButton("Btn1", this) << new QPushButton("Btn2", this) << new QPushButton("Btn3", this); } void EightMyPlan::updateAllButtonsLayout() { for (QPushButton* btn : buttonList) { if (btn) { btn->setFixedSize(120, 40); btn->setStyleSheet( "QPushButton {" " background-color: #5DADE2;" " border-radius: 6px;" " color: white;" "}" "QPushButton:hover {" " background-color: #3498DB;" "}"); } } } ``` #### 在 MainWindow 中调用(确保对象存在) ```cpp // mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include "eightmyplan.h" void MainWindow::CreateScrollArea() { EightMyPlan* planWidget = new EightMyPlan(this); planWidget->updateAllButtonsLayout(); // 现在能正常链接! } ``` --- ### 总结 | 问题 | 解决方案 | |------|----------| | 函数只有声明无定义 | 在 `.cpp` 中实现函数 | | `.cpp` 文件未加入项目 | 检查 `.pro` 文件或 Qt Creator 项目结构 | | 函数签名不匹配 | 确保声明与定义一致(参数、const、返回值) | | 编译缓存问题 | 清理重建 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值