析构函数(2019.8.13)

本文深入解析析构函数的概念,强调其在对象生命周期结束时的作用,包括内存释放和善后处理。详细介绍了析构函数的定义规则,如名称、参数及返回值特性,以及在类中唯一性的原则。通过实例演示了析构函数的使用场景,特别是与构造函数配合进行资源分配与回收的过程。

析构函数

1.析构函数概述

与构造函数相类似的,析构函数也是一种特殊的成员函数,也被声明为公有成员。不同的是,析构函数作用时释放分配给对象的内存空间,并做一些善后工作。析构函数在声明定义和使用的时候需要注意如下的事项:
(1)析构函数的名字必须与类名相同,但在名字的前面要加上波浪号(“~”)
(2)析构函数没有参数,没有返回值,不能重载,在一个类中只能有一个析构函数。
(3)当撤消对象时,系统会自动调用析构函数完成空间的释放和善后工作。

在使用析构函数中,需要注意如下的几个问题:
(1)每个类必须有一个析构函数,若没有显式地定义,则系统会自动生成一个默认析构函数,它是一个空函数。

类名∷默认析构函数名(){ }

例如,有以下程序:

#include //定义类Sample
using namespace std;
class Sample
{
int n; //默认为私有数据成员
public:
Sample(){n=0;} //构造函数1
Sample(int i){n=i;} //构造函数2
~Sample() //析构函数
{
cout<<”调用析构函数:n=”<<n<<endl;
}
};

int main()
{
Sample s1,s2(10);
}

对于大多数类而言,默认的析构函数就能满足要求,但如果对象在完成操作前需要做内部处理,则应显式地定义析构函数。

构造函数和析构函数的常见用法是,在构造函数中用new运算符为对象分配空间,在析构函数中用delete运算符释放空间。

#include <iostream>
using namespace std;
#include <math.h>
class complex
{
	double real,imag;
public:
	complex(double real=0.0, double imag=0.0);  //声明构造函数
	~complex();                            //声明析构函数  
	double abscomplex();
};
complex::complex(double r, double i)           //定义构造函数
{
	cout<<"constructing……"<<endl;
	real=r;
	imag=i;
}
complex::~complex()         //定义析构函数
{  
	cout<<"destructing……"<<endl;
}
double complex::abscomplex()
{
	double n;
	n=real*real+imag*imag;
	return sqrt(n);
}
int main()
{
	complex ob(1.1,2.2);
	cout<<"abs of complex ob="<<ob.abscomplex()<<endl;
}
<think>好的,我现在需要解决用户在Qt项目中遇到的LNK2019链接错误问题。首先,我需要回顾用户提供的错误信息。用户提到在VS2019中编译时出现了“unresolved external symbol”错误,涉及testDialog类的构造函数和析构函数。这通常意味着编译器能找到这些类的声明,但链接器找不到它们的实现。 首先,我应该考虑常见的导致LNK2019错误的原因。最常见的情况是头文件中的函数或类声明了但没有对应的实现。用户可能创建了testDialog类,并在头文件中声明了构造函数和析构函数,但没有在对应的源文件中实现它们。或者,可能源文件没有被正确包含到项目里,导致编译时没有生成相应的.obj文件。 接下来,我需要检查构建过程中的文件是否完整。用户提到在QtCreator中创建了新的窗口类,并在VS2019中出现错误。这可能是因为VS2019的项目文件没有自动更新,导致新增的.cpp文件没有被包含到编译过程中。这时候需要重新运行qmake来更新项目文件,或者手动在VS中添加新文件。 另一个可能性是命名空间或类名的拼写错误。用户可能在头文件和源文件中的类名不一致,比如大小写错误或者拼写错误,导致链接器找不到对应的实现。例如,头文件中的类名是testDialog,而源文件中可能写成了TestDialog或其他形式。 此外,Qt的元对象编译器(moc)也可能导致问题。如果用户在新创建的窗口类中没有包含Q_OBJECT宏,或者没有正确运行moc生成对应的moc文件,就会导致链接错误。特别是当类中使用信号和槽时,必须确保Q_OBJECT宏的存在,并且生成moc文件。 用户可能在多个地方调用了testDialog类,比如在MainWindow的某个槽函数中。如果此时testDialog的.cpp文件没有被正确编译,就会导致链接错误。需要检查该类的.cpp文件是否在项目中,并且是否被正确编译生成.obj文件。 另外,还要注意构建目录的清理问题。有时候旧的编译产物可能残留,导致链接器使用过时的.obj文件。这时候需要清理项目并重新构建,以确保所有文件都是最新的。 总结可能的解决方案步骤:首先检查testDialog类的声明和实现是否一致,确保源文件已添加到项目;重新运行qmake并清理构建目录;检查Q_OBJECT宏和moc文件的生成;确认没有拼写错误或语法错误。此外,还要考虑项目配置是否正确,比如库的链接和包含路径的设置。</think>### Qt项目LNK2019链接错误解决方案 #### 问题分析 Qt项目中出现`LNK2019: unresolved external symbol`错误,通常是因为**声明与实现未正确匹配**或**编译系统未更新**。根据错误信息: ``` 1>MainWindow.obj : error LNK2019: unresolved external symbol "public: __thiscall testDialog::testDialog(class QWidget *)" ``` 表明`testDialog`类的构造函数和析构函数未找到实现[^2]。以下是分步解决方案: --- #### 步骤1:检查类声明与实现 1. **验证头文件与源文件对应关系** - 确保`testDialog`类的声明(`.h`文件)和实现(`.cpp`文件)文件名一致,例如: ```cpp // testdialog.h class testDialog : public QDialog { Q_OBJECT // 必须包含Q_OBJECT宏 public: explicit testDialog(QWidget *parent = nullptr); ~testDialog(); }; ``` ```cpp // testdialog.cpp #include "testdialog.h" testDialog::testDialog(QWidget *parent) : QDialog(parent) {} // 构造函数实现 testDialog::~testDialog() {} // 析构函数实现 ``` - 若`.cpp`文件中未实现构造函数/析构函数,会导致链接错误[^2]。 2. **检查类名和作用域** - 确保类名在头文件和源文件中完全一致(包括大小写)。 --- #### 步骤2:更新编译系统 1. **重新生成Qt项目文件** - 在Qt Creator中执行以下操作: 1. 点击菜单栏:**构建(Build) → 清理项目(Clean Project)**。 2. 点击菜单栏:**构建(Build) → 执行qmake(Run qmake)**。 3. 重新编译项目。 - **原因**:新增文件后,VS2019可能未自动更新`.vcxproj`文件,需通过qmake重新生成[^2]。 2. **手动添加缺失的源文件** - 在VS2019中右键项目 → **添加(Add) → 现有项(Existing Item)**,选择`testdialog.cpp`。 --- #### 步骤3:处理Qt元对象系统 1. **检查Q_OBJECT宏** - 若`testDialog`类包含信号/槽或Qt元对象特性,必须添加`Q_OBJECT`宏: ```cpp class testDialog : public QDialog { Q_OBJECT // 必须添加 // ... }; ``` - **未添加此宏**会导致moc未生成对应代码,引发链接错误。 2. **手动触发moc生成** - 删除构建目录下的`moc_*.cpp`文件(如`moc_testdialog.cpp`),重新编译项目。 --- #### 步骤4:验证构建配置 1. **检查文件编码与换行符** - 若`.h`/`.cpp`文件使用UTF-8 BOM编码或混合换行符(LF/CRLF),可能导致VS2019解析异常。建议统一为**UTF-8无BOM + LF换行**。 2. **清理临时文件** - 删除`build`目录下所有文件(或执行`git clean -dfx`),重新编译。 --- #### 步骤5:扩展验证 若问题仍未解决,可进一步检查: 1. **库依赖**:确保项目`.pro`文件中包含`QT += widgets`(若使用Qt Widgets模块)。 2. **命名空间冲突**:避免自定义类名与Qt内置类名重复。 3. **语法错误**:某些编译器会因语法错误跳过后续编译步骤,需检查所有文件的语法。 --- #### 典型修复案例 1. 用户新增`testdialog.h`/`testdialog.cpp`后未执行qmake → 重新运行qmake后解决。 2. 用户忘记在`.cpp`文件中实现析构函数 → 添加`testDialog::~testDialog() {}`后解决[^2]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值