前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >通俗易懂的解释C++的构造函数

通俗易懂的解释C++的构造函数

作者头像
混说Linux
发布2022-07-14 20:46:55
3610
发布2022-07-14 20:46:55
举报
文章被收录于专栏:混说Linux混说Linux

1

你买了套房,住进去之前得先装修。 你买个硬盘,用之前得先分区。 你买个手机,用之前得先装上sim卡、下载一些必要软件、注册/登录微信/支付宝账户。

创建一个对象也一样:你得到了一块内存;这块内存可能是“二手房”,前任留下的shit什么的都还留在里面,你得先清理(把内容置零)、重新装修(设置一些基础信息)之后才能入住。

过去,C时代,这些都得你自己照应。如果你忘了,那么访问了未初始化存储区、读出乱七八糟的东西,你就自认倒霉吧。

C++时代,人们变聪明了:既然装修是入住前的必要步骤,我干脆把它固定到你的《购房流程指导书》里算了。你交钱买房后,就会有人领你看房、给你谈装修事宜。

这个固定的、执行装修事宜的步骤就是构造函数。

用伪码表示的话,对象创建流程是这样的:

  1. 用各种奇怪的方式得到一块内存
  2. 执行构造函数,“装修”这块内存
  3. 拎包入住

每个人都有自己独特的口味,每个用户自定义对象也有不同的初始化流程。

因此,C++做了一个约定:和类名相同的无返回函数就是它的初始化函数(构造函数),编译器保证在创建一个对象之后、允许你使用它之前,它必定会在这个对象对应的内存上执行构造函数,按你的要求把对象装修好。如果你不写,那么它默认给你个毛坯房(这就是所谓的“默认构造函数”)。

举例来说,你打算写个网游,其中有一个魔法师角色,那么当new一个新的魔法师对象时,你就要给它弄上一套默认的初始装备:

代码语言:javascript
复制
class Mage {
    Mage() {
        //new一个白板法杖
        //new一件普通法袍
    }
    Mage(法杖类型 法杖, 法袍类型 法袍) {
        //按传入的法杖类型new一根法杖
        //按传入的法袍类型new一件法袍
    }
}

现在,你声明一个法师对象,对应的构造函数就被调用了:

代码语言:javascript
复制
//自动执行Mage(),为它添加一根白板法杖和一件普通法袍
Mage babyMage; 
//自动执行Mage(法杖类型 法杖, 法袍类型 法袍),给它一套NB的装备
Mage superMage(天使之杖, 神圣裹尸布); 

一般来说,你写了自己的构造函数,就有必要写出自己的析构函数。这样删除法师对象时,可以把new给他的装备一起删掉,以免造成内存泄漏:

代码语言:javascript
复制
class Mage {
    Mage() {
        //new一个白板法杖
        //new一件普通法袍
    }
    Mage(法杖类型 法杖, 法袍类型 法袍)    {
        //按传入的法杖类型new一根法杖
        //按传入的法袍类型new一件法袍
    }
    ~Mage() {
        //删除法杖、法袍等对象
    }
}

C++保证在你调用delete时,先自动调用析构函数(而我们安排在这个函数里面删除它的法杖、法袍等对象),再删除对象占用的内存。

以上,就是所谓的RAII机制(Resource Acquisition Is Initialization)。

等你有了一定的开发经验,那么一定经常听到“(资源)谁申请谁释放”原则。基于这个原则才能清晰、准确的界定资源的生存期、控制权。

而RAII天然保证了这个原则被严格执行:如果任何类/对象都严格的管好自己申请的资源、并在析构时确保这些资源被无遗漏的归还;那么对一个熟练掌握了RAII的程序员来说,只要一个对象的生存期、所有权、引用关系(计数)在设计之初都理清楚了,资源泄露就是不可能的。

为了清晰表达“所有权转移、复制”等相关语义,C++标准库才提供了shared_ptr、unique_ptr、weak_ptr等“智能指针”;更有趣的是,这些“智能指针”同样是借助于有保障的构造/析构函数的自动调用机制设计的。你必须先透彻理解构造/析构函数,才有可能明白它们的工作原理、甚至自己实现它们(没错,过去那个C++标准化/STL库总是跟不上趟的年代里,很多程序员在自己的工程里手工编写过shared_ptr)。

因此,当其它语言的程序员觉得离开“垃圾回收”都活不成时,资深C++程序员轻蔑的说“资源可不仅仅是内存”——没有严格的RAII机制,没有构造/析构函数调用时机的可靠保证,其它语言在管理内存之外的资源时,反而要比C++困难。

原文:https://www.zhihu.com/answer/1236427106

版权归原作者所有,如有侵权,请联系删除。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-07-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 混说Linux 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档