目录
4.2 引发了异常: 读取访问权限冲突。this 是 nullptr。
前言
最近开发上位机的过程中遇到了不少报错,大部分其实都是细节上的错误,或者是因为不熟悉导致的。这里将最近遇到的报错和解决方法一一列举,解决方法并不全面,或者并不是最好的办法,但是确实是在当时解决了我的问题。
首先声明一下环境的问题,编译器采用visual studio2022
Qt版本6.5.3
1.错误:C7624
描述:类型名称“ClassA”不能出现在类成员访问表达式的右侧
这个错误和后面的几个错误不算是常见,但是感觉新手经常会范。主要原因在于头文件的定义错误,将构造函数放到了信号槽里面。
比如下面的示例:
class ClassA: public QObject
{
Q_OBJECT
public:
public slots:
ClassA(QObject *parent); //应当放在public中
~ClassA(); //同上
void slot();
};
提一句,如果控制台出现报错,涉及信号和槽的,一般就是找不到信号或者找不到槽。把connect函数重头捋一遍,每一个类能不能找到,引用的类名、方法名大小写一不一致,能不能跳转。如果都检查没问题,看一下引用的槽函数是不是在头文件中放在了槽函数的位置,也就是public slots:下面。
2.错误:"C2143" "C4430" "C2238"
描述:
如果真的是少了什么分号,那就别说了,但是如果检查之后确定没少分号,并且是这三个错误同时出现,那么检查一下。是不是出现了头文件互相包含的问题。
我这里出错的原因是,一个公共区域包含了所有头文件,结果公用方法类调用了公共区域,功能类又调用了公用方法类。
或者是ClassA使用ClassB的方法,ClassB也想使用ClassA的方法,就会出现这种情况。
解决方法:一方面确认一下是不是真的需要这样引用头文件,可能是逻辑上出现了某些错误导致互相包含了。
另一方面如果必须互相引用可以使用前置声明的方法。(有需要可以自己去搜一下)
3.错误:MSB4181
描述:“QtRunWork”任务返回了false,但未记录错误
这个和错误1很像,同样是头文件里面的函数放错了位置。这里是私有成员变量可能放到了槽函数的位置上。具体就不用多说了,检查一下私有成员变量吧。
4. 初始化问题
描述:
SharedMethod::SharedMethod() : tcpSocket(new QTcpSocket(this)){}
以上代码出现报错,没有与参数列表匹配的构造函数 "QTcpSocket::QTcpSocket" 实例 参数类型为: (SharedMethod *)
并且在tcpSocket->state()运行时出现引发了异常读取访问权限冲突this是nullptr
这其实是两个问题,我们一个一个来说
4.1 以上代码出现报错,没有与参数列表匹配的构造函数 "QTcpSocket::QTcpSocket" 实例 参数类型为: (SharedMethod *)
出现这个问题的原因可能是由于 SharedMethod 类没有继承自 QObject,而 QTcpSocket 构造函数需要一个继承自 QObject 的父对象来管理其生命周期。
那么解决方法就很简单了
确保 SharedMethod 类继承自 QObject,并正确初始化 QObject 部分。
初始化注意QObject* parent不要忘记,如果出现这个报错,很可能你已经自己创建过一个构造函数进行尝试了,或者vs使用了vs自动生成的构造函数。那么很大可能会忘记QObject* parent要写上。同样的: QObject(parent)也不要忘记。
注意,头文件中也加上QObject* parent = nullptr,我就是之前自己创建完发现依旧报错,结果查了半天发现是这里忘加了。
//SharedMethod.cpp
SharedMethod::SharedMethod(QObject* parent)
: QObject(parent),
tcpSocket(new QTcpSocket(this))
{
}
//SharedMethod.h
class SharedMethod : public QObject
{
Q_OBJECT
public:
SharedMethod(QObject* parent);
~SharedMethod();
private:
QTcpSocket* tcpSocket;
};
4.2 引发了异常: 读取访问权限冲突。this 是 nullptr。
在别的方法调用CheckConnect函数时tcpSocket->state()出现报错
这个实际上和上一个问题一样,都是初始化的问题,如果按照上面的步骤一步步完成,应该不会出现这个报错了。如果还有,检查一下自己的初始化步骤,当然还有一点,检查一下你改的是不是程序执行位置的代码。(我之前改完依旧报错,结果发现改得是另一个功能的相同代码。)
注意,如果是多层的结构,不止要检查被引用的方法是否正常初始化,还要检查引用它的方法是不是正常初始化,同时还要检查一下引用引用它的方法是不是正常初始化了。
类比一下就是功能类的公用方法类报错,除了检查功能类之外,还要检查控制功能类的类是否正确初始化了功能类。
5.C4996
描述:xxx被声明为已否决
不知道是不是vs编译器特有的错误哈,可能是使用的函数版本太老了,或者是已经弃用了。
解决方法是关闭VS中的SDL检测。
右键项目→属性→C/C++→常规→SDL检查→改为否