C++ 析构函数

C++ 析构函数C 析构函数我使用的继承开发环境 VisualStudio 设计一个类时 如何写析构函数 析构函数如果我们不写的话 C 会帮我们自动的合成一个 就是说 C 会自动的帮我们写一个析构函数 很多时候 自动生成的析构函数可以很好的工作 但是一些重要的事迹 就必须我们自己去写析构函数 析构函数和构造函数是一对 构造函数用于创建对象 而析构函数是用来撤销对象 简单的说 一个

C++ 析构函数

我使用的继承开发环境: Visual Studio 2010


下面我们来做一个例子,看看:

#include 
     #include 
     using namespace std; class NoName{ public: NoName():pstring(new std::string), i(0), d(0){} private: std::string * pstring; int i; double d; }; int main(){ return 0; }

像上面这个 NoName 类这样的设计,类里面有一个成员变量是指针(std::string *pstring) ,那么在构造函数里我们使用 new 创建了对象,并使用 pstring 来操作这个对象。那么在这个情况下,我们就必须设计一个析构函数。

析构函数是这样编写的:(可以在类的里面声明,定义写在类的外面,)

class NoName{ public: NoName():pstring(new std::string) , i(0), d(0){ cout << "构造函数被调用了!" << endl; } ~NoName();
NoName::~NoName(){ cout << "析构函数被调用了!" << endl; }

析构函数是这样写的: ~NoName() ,它与构造函数唯一的区别就是,前面都加了一个 ~ 符号。 析构函数都是没有参数的,也就是说:析构函数永远只能写一个。
按照 C++ 的要求,只要有 new 就要有相应的 delete 。这个 new 是在构造函数里 new 的,就是出生的时候。所以在死掉的时候,就是调用析构函数时,我们必须对指针进行 delete 操作。

我们来在main() 函数中创建一个 NoName 实例对象来 测试一下:

int main(){ NoName a; return 0; }

并且在 main() 函数的 } 这一行添加一个断点,如图所示:

这里写图片描述

运行输出:

构造函数被调用了! 析构函数被调用了!

在定义 a 对象的时候,调用了 NoName 类的构造函数,在main() 函数执行完的时候,就是执行完 return 0; 这句话后,main() 函数的执行域结束,所以就要杀掉 a 对象,所以这个时候会调用 NoName 类的析构函数。

那么,如果我们在 main() 函数中使用 new 关键字来创建一个 NoName 类的实例化对象,会出现什么样的运行效果呢?
main() 函数中的代码如下:

int main(){ NoName a; NoName *p = new NoName; return 0; }

运行输出:

构造函数被调用了! 构造函数被调用了! 析构函数被调用了!

这里使用 new 创建的对象,就必须要使用 delete 来释放它。 牢牢的记住:newdelete 是一对。正确的代码是下面这个样子的:

int main(){ NoName a; NoName *p = new NoName; delete p; return 0; }

运行输出:

构造函数被调用了! 构造函数被调用了! 析构函数被调用了! 析构函数被调用了!

赋值构造函数:

在赋值的时候,不是讲指针赋值过来,而是将指针对应指向的字符串赋值过来,这是最关键的一步。

因为我们写了析构函数,就必须要将赋值构造函数写上:

class NoName{ public: NoName():pstring(new std::string) , i(0), d(0){ cout << "构造函数被调用了!" << endl; } NoName(const NoName & other); ~NoName();
NoName::NoName(const NoName & other){ pstring = new std::string; *pstring = *(other.pstring); i = other.i; d = other.d; }

除了要写 赋值构造函数,还要写赋值操作符。

class NoName{ public: NoName():pstring(new std::string) , i(0), d(0){ cout << "构造函数被调用了!" << endl; } NoName(const NoName & other); ~NoName(); NoName& operator =(const NoName &rhs);
NoName& NoName::operator=(const NoName &rhs){ pstring = new std::string; *pstring = *(other.pstring); i = other.i; d = other.d; return *this; }

只要你写了析构函数,就必须要写 赋值构造函数 和 赋值运算符,这就是著名的 三法则 (rule of three



总结:

在设计一个类的时候,如果我们一个构造函数都没有写,那么 C++ 会帮我们写一个构造函数。只要我们写了一个构造函数,那么 C++ 就不会再帮我们写构造函数了。

构造函数可以重载,可以写很多个,析构函数不能重载,只能写一个。如果我们没有写析构函数,C++会自动帮我们写一个析构函数。那么在工作的时候,我们写的析构函数会被调用,调用完成之后,C++会执行它自动生成的析构函数。

如果我们写的类是一个没有那么复杂的类,我们可以不需要写析构函数。如果一个类只要有这些情况:打开文件、动态分配内存、连接数据库。简单的说:就是只要构造函数里面有了 new 这个关键词,我们就需要自己手动编写析构函数。

那么如果我们写了析构函数,就必须要注意三法则:同时编写:析构函数、赋值构造函数、赋值运算符。

完整的代码:

#include 
         #include 
         using namespace std; class NoName{ public: NoName():pstring(new std::string) , i(0), d(0){ cout << "构造函数被调用了!" << endl; } NoName(const NoName & other); ~NoName(); NoName& operator =(const NoName &rhs); private: std::string * pstring; int i; double d; }; NoName::~NoName(){ cout << "析构函数被调用了!" << endl; } NoName::NoName(const NoName & other){ pstring = new std::string; *pstring = *(other.pstring); i = other.i; d = other.d; } NoName& NoName::operator=(const NoName &rhs){ pstring = new std::string; *pstring = *(rhs.pstring); i = rhs.i; d = rhs.d; return *this; } int main(){ NoName a; NoName *p = new NoName; delete p; return 0; }
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/222560.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午3:31
下一篇 2026年3月17日 下午3:31


相关推荐

  • pytest skipif_pytest不是内部或外部命令

    pytest skipif_pytest不是内部或外部命令前言pytest.mark.skip可以标记无法在某些平台上运行的测试功能,或者您希望失败的测试功能Skip和xfail:处理那些不会成功的测试用例你可以对那些在某些特定平台上不能运行的测试用

    2022年7月30日
    8
  • shell编程和shell脚本_shell脚本语言入门pdf

    shell编程和shell脚本_shell脚本语言入门pdf看了一遍,小有问题,但是可以览个大概了。 Shell编程基础http://wiki.ubuntu.org.cn/Shell%E7%BC%96%E7%A8%8B%E5%9F%BA%E7%A1%80

    2022年10月3日
    6
  • phpstorm激活码2022.01.13(JetBrains全家桶)2022.03.06

    (phpstorm激活码2022.01.13)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年4月2日
    125
  • 手把手教程:0.02/张接入GPT Image 1.5 API!GrsAi国内直连完整指南,速度超快

    手把手教程:0.02/张接入GPT Image 1.5 API!GrsAi国内直连完整指南,速度超快

    2026年3月16日
    4
  • FMX探索之IMAGE控件上输出

    FMX探索之IMAGE控件上输出承上篇话说直接在窗体上绘制有欠美观 那就画在 IMAGE 控件上吧 拖一个 IMAGE 控件出来 改下代码 procedureTFo Button2Click Sender TObject beginCanvas BeginScene Image1 Canvas FillText RectF 0 0 100 30 HelloWorld false 1

    2026年2月21日
    3
  • APP性能测试之功耗测试

    APP性能测试之功耗测试APP 性能测试之功耗测试功耗 通俗的理解即电流通过导体使设备运行 导体本身的电阻将电能转换为热能的过程 因此 通常功耗测试也叫电量测试 耗电量测试是指测试 App 在运行过程中消耗的能量 设备运行期间消耗能量公式 W w t U I tw 表示单位时间耗电量 U 为电池供电电压 I 为电流值 t 为测试时间通常来说 U 可以认为不变 对于平稳的测试过程 耗电量与测试时间成正比 移动设备功耗由于移动设备的电池容量限制 所以对于 App 的功耗也是需要考虑的一个方面 Andro

    2026年3月16日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号