我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C++的构造函数和析构函数是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C++的构造函数和析构函数是什么

本篇内容主要讲解“C++的构造函数和析构函数是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++的构造函数和析构函数是什么”吧!

目录
  • 一、构造函数

  • 二、C++类的内存模型

    • 1、只定义成员函数

    • 2、往空类中添加静态成员变量

    • 3、再加入非静态成员变量

  • 三、this指针

    • 四、析构函数

      一、构造函数

      首先,由于类只是一个模板,因此我们在定义类时无法对成员变量初始化,比如下面代码就是错误的:

      class circle{public:    int m_L = 20;// Error:不允许使用数据成员初始值设定项};

      因此,初始化只能发生在类创建对象的过程中,但是由于访问权限的原因,无法在类外访问某些成员变量,因此下面这种做法有时候是无效的:

      circle C1;// 实例化一个对象 C1C1.m_L = 20;// 通过创建的对象,来给对应变量初始化,但是如果m_L是private访问权限,则失效

      为了解决这个问题,让程序员能像使用标准数据类型一样适用对象,在类内提供了一个特殊的成员函数——“构造函数”,专门用于在创建对象时初始化类对象。之所以说它特殊,是因为C++已经自动为构造函数提供了名称和使用语法,程序员只需要提供方法的定义即可,即:类名(形参列表)。具体来说,构造函数的定义如下:

      class circle{public:    int m_L;public: //成员函数(方法)    circle(const int a)//通过构造函数对成员变量进行赋值    {        m_L = a;    }};circle C1(20);//调用格式cout << "C1.m_L:" << C1.m_L <<endl;

      看上去似乎很简单,但是由于构造函数也是函数,因此所有C++中的形参传递方式,函数特性以及函数调用方法都能用于构造函数。 如前文所讲,C++会自动给类添加一个空的构造函数,但是如果自己在类中实现了有参构造函数,编译器便不再提供无参构造函数。举例如下:

      class circle{public:    int m_L;public: //成员函数(方法)    circle(const int a)//通过构造函数对成员变量进行赋值    {        m_L = a;    }};circle C1(20);//调用格式正确,能够通过构造函数赋值circle C2; //错误,自己定义了有参构造函数,不再提供无参构造函数

      构造函数可以重载,接着上面的例子,如果重载一个空的构造函数,那么两个调用格式都正确:

      class circle{public:    int m_L;public: //成员函数(方法)    circle(){}// 空构造函数    circle(const int a)//通过构造函数对成员变量进行赋值    {        m_L = a;    }};circle C1(20);//调用格式正确,能够通过构造函数赋值circle C2; //正确,可以通过重载的空构造函数实现初始化

      构造函数的参数不仅可以是标准数据类型,也可以是类。众所周知,在数值作为函数参数进行传递的时候,会重新拷贝出来一份数据作为参数传递用完即销毁,这种方式不仅浪费了内存空间,而且无法修改原始数据。为了结合这两者之间的优点,于是经常采取引用作为函数的参数。虽然引用是指针的一种特殊情况,但是指针太过于灵活,并且引用在形式上引用与普通的变量地用法并没有什么区别,因此使用起来更加方便。

      class circle{public:    int m_L;public: //成员函数(方法)    circle(){}// 空构造函数    circle(const int a)//通过构造函数对成员变量进行赋值    {        m_L = a;    }    //引用作为函数参数传递,并用const修饰,节省空间的同时避免修改原数据    circle(const circle& sub_circle)    {        m_L = sub_circle.m_L;    }};circle C1(20);//调用格式正确,能够通过构造函数赋值circle C2(C1); //正确,可以通过拷贝构造函数进行初始化

      二、C++类的内存模型

      C++中,一个类包括:

      • 成员变量:静态成员变量和普通成员变量

      • 成员函数:静态成员函数和普通成员函数

      虽然为了集成,我们将其写到一个类里面,但是只有普通成员变量真正属于类的对象,类的所有对象共享一份静态成员函数,静态成员变量和普通成员函数。画出了内存模型,如下图所示:

      C++的构造函数和析构函数是什么

      为了进一步理解,我们举例如下:

      2.1、只定义成员函数

      class person{public:    // 定义一个空的构造函数person(int m_age, int m_ID){}};person p1(10, 20);cout << "p1 所占的空间为:" << sizeof(p1) << endl;

      输出结果为:

      p1 所占的空间为:1

      这个题目在《剑指offer》一书中也提到过,由空类实例化出来的对象所占的内存空间是1个而不是0个字节,因为编译其给对象 p1 分配了一个地址,来表示不同的对象存储在不同的地址空间,因此占用1个字节。

      2.2、往空类中添加静态成员变量

      class person{    static int age; //静态成员变量,存在全局区,不属于类对象的一部分    static int ID;  //静态成员变量,存在全局区,不属于类对象的一部分public:    // 定义一个空的构造函数person(int m_age, int m_ID){}};person p1(10, 20);cout << "p1 所占的空间为:" << sizeof(p1) << endl;

      输出结果为:

      p1 所占的空间为:1

      当向类中加入了成员函数与静态成员变量时,类的实例化对象仍然只占用1个字节的空间,足以证明这些函数和变量并不是类对象的一部分。

      2.3、再加入非静态成员变量

      class person{    static int age; //静态成员变量,存在全局区,不属于类对象的一部分    static int ID;  //静态成员变量,存在全局区,不属于类对象的一部分    int a;//非静态成员变量,存在栈区,属于类对象的一部分public:person(int m_age, int m_ID){}};

      输出结果为:

      p 所占的空间为:4

      因此当向类中加入了非静态成员变量时,类的实例化对象占用4个字节的空间,可以说明,非静态变量属于类对象的一部分。综上:同一个类所有实例化出来的对象共享同一份静态成员变量,所以一改全改。既然同一个类的不同对象共享同一份成员函数,那么成员函数怎么区分该访问哪个对象的普通成员变量呢?

      三、this指针

      接着上一小节的问题,this指针为上述问题提供了一个完美的解决方案,它指向用来调用成员函数的对象(被当作参数隐式地传递给成员函数),我们通过一张图来理解它:

      C++的构造函数和析构函数是什么

      此外,this指针的另一个用途是当成员函数需要返回对象时,用 return *this; 或者 return this,这种做法能够实现链式编程。比如:

      p2.addPerson(p1).addPerson(p1);

      首先,对象 p2 调用成员函数 addPerson(p1) ,其返回值继续调用 addPerson(p1),此时返回值就必须也是 person 类型才可以,因此使用 this 指针可以完成需求。先来看第一个例子:

      class person{public:int age;person(int age){this->age = age; // this指针区分调用者}// 返回值为person类型,且参数加上了const限制,防止修改原数据person addPerson(const person& p){this->age += p.age;// 主要实现两个类对象年龄的相加return *this;// 由于返回值是person,因此返回 *this}};person p1(20);person p2(10);person p3 = p2.addPerson(p1).addPerson(p1);cout << "p1 age:" << p1.age << endl;cout << "p2 age:" << p2.age << endl;cout << "p3 age:" << p3.age << endl;

      首先,通过构造函数分别对 p1,p2 赋了初值,然后 p2 调用函数 addPerson(p1) 修改自身的变量 age 。**由于函数通过值传递的方式返回 person 类型,所以将整个 person 类型复制了一份返回,返回值继续调用 addPerson(p1), **最后的结果赋值给了新的对象 p3。所以输出结果为:

      p1 age:20

      p2 age:30

      p3 age:50

      但是如果函数 addPerson() 修改为:

      person& addPerson(const person& p){    this->age += p.age;// 主要实现两个类对象年龄的相加    return *this;// 虽然返回值是person&,返回值的类型也是 *this}person p1(20);person p2(10);person p3 = p2.addPerson(p1).addPerson(p1);cout << "p1 age:" << p1.age << endl;cout << "p2 age:" << p2.age << endl;cout << "p3 age:" << p3.age << endl;

      与上例唯一的区别就在于返回值的类型变成了引用,那么每次返回的就变成了该对象本身,而非在值传递中拷贝出来的那一份数据。那么输出就变成了:

      p1 age:20

      p2 age:50

      p3 age:50

      四、析构函数

      用构造函数创建对象后,程序负责跟踪该对象,知道其过期为止。当对象过期时,程序自动调用析构函数完成清理工作。与构造函数一样,C++默认提供了一个空的析构函数,定义为:~类名( )。由于开辟在栈区的变量程序会自动释放,因此不需要析构函数执行清理工作,但是当程序员在堆区开辟空间时,需要手动执行清理工作,这时候需要析构函数来释放堆区内存。比如:

      ~person(){// 在析构函数内写入需要执行的代码cout << "调用析构函数" << endl;}person p1(20);person p2(10);// 在生命周期结束后自动调用析构函数执行清理工作

      输出为:

      调用析构函数

      调用析构函数

      到此,相信大家对“C++的构造函数和析构函数是什么”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

      免责声明:

      ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

      ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

      C++的构造函数和析构函数是什么

      下载Word文档到电脑,方便收藏和打印~

      下载Word文档

      猜你喜欢

      C++的构造函数和析构函数是什么

      本篇内容主要讲解“C++的构造函数和析构函数是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++的构造函数和析构函数是什么”吧!目录一、构造函数二、C++类的内存模型2.1、只定义成员函数
      2023-06-20

      C#中构造函数和析构函数的区别是什么

      这篇文章将为大家详细讲解有关C#中构造函数和析构函数的区别是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。C#构造函数和析构函数在你可以访问一个类的方法、属性或任何其它东西之前, ***
      2023-06-18

      C#中构造函数和析构函数的作用是什么

      本篇文章给大家分享的是有关C#中构造函数和析构函数的作用是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。C#构造函数(constructor)包括实例C#构造函数和静态C#
      2023-06-17

      C++中构造函数和析构函数有什么作用

      构造函数是一种特殊的成员函数,用于在创建对象时初始化对象的数据成员。构造函数的作用是初始化对象的状态,为对象的数据成员赋初值,确保对象在创建时具有合适的状态。析构函数是一种特殊的成员函数,用于在对象被销毁时清理对象所占用的资源。析构函数的
      C++中构造函数和析构函数有什么作用
      2024-03-11

      C++ 函数重载是否适用于构造函数和析构函数?

      c++++ 构造函数支持重载,而析构函数不支持。构造函数可具有不同的参数列表,而析构函数只能有一个空参数列表,因为它在销毁类实例时自动调用,不需输入参数。C++ 中函数重载是否适用于构造函数和析构函数?引言函数重载允许函数在名称相同的情
      C++ 函数重载是否适用于构造函数和析构函数?
      2024-04-14

      C++构造函数与析构函数怎么使用

      这篇文章主要讲解了“C++构造函数与析构函数怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++构造函数与析构函数怎么使用”吧!对象的初始化和清理生活中我们买的电子产品都基本会有出厂
      2023-07-02

      C++析构函数是什么

      本篇内容介绍了“C++析构函数是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!析构函数(destructor) 与构造函数相反,当对象脱
      2023-06-17

      C++修炼之构造函数与析构函数

      本章节我们将学习类的6个默认成员函数中的构造函数与析构函数,并对比C语言阶段的内容来学习它们的各自的特性,感兴趣的同学可以参考阅读
      2023-05-14

      C++构造函数的特性是什么

      这篇文章主要介绍“C++构造函数的特性是什么”,在日常操作中,相信很多人在C++构造函数的特性是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++构造函数的特性是什么”的疑惑有所帮助!接下来,请跟着小编
      2023-07-02

      C++的拷贝构造函数是什么

      这篇文章主要介绍了C++的拷贝构造函数是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。拷贝构造函数用以将一个类的对象拷贝给同一个类的另一个对象,比如之前学习过的strin
      2023-06-29

      什么是java构造函数

      构造函数是面向对象中的一员,构造函数可以叫做构造器,它的函数名与类名相同,不用定义返回值类型,也没有具体的返回值。构造函数是在构建创造时对象时调用函数,作用是可以给对象进行初始化,创建对象都必须要通过构造函数初始化。一个类中如果没有定义过构造函数,那么该类会有
      什么是java构造函数
      2021-05-19

      C#结构体构造函数的实例分析

      这期内容当中小编将会给大家带来有关C#结构体构造函数的实例分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。C#结构体构造函数的应用是如何的呢?C#结构体构造函数的实例1、 /// ﹤summary
      2023-06-18

      C++虚析构函数的作用是什么

      C++虚析构函数的作用是确保在通过基类指针删除派生类对象时能正确调用派生类的析构函数,以避免内存泄漏和其他问题。当基类指针指向一个派生类对象并且在删除指针时没有使用虚析构函数时,只会调用基类的析构函数,而不会调用派生类的析构函数,导致派生类
      C++虚析构函数的作用是什么
      2024-03-11

      python构造函数指的是什么

      小编给大家分享一下python构造函数指的是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!python的五大特点是什么python的五大特点:1.简单易学,开
      2023-06-14

      java中构造函数是什么

      构造函数是面向对象中的一员,构造函数可以叫做构造器,它的函数名与类名相同,不用定义返回值类型,也没有具体的返回值。构造函数是在构建创造时对象时调用函数,作用是可以给对象进行初始化,创建对象都必须要通过构造函数初始化。(推荐学习:java课程)一个类中如果没有定
      java中构造函数是什么
      2021-06-06

      编程热搜

      • Python 学习之路 - Python
        一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
        Python 学习之路 - Python
      • chatgpt的中文全称是什么
        chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
        chatgpt的中文全称是什么
      • C/C++中extern函数使用详解
      • C/C++可变参数的使用
        可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
        C/C++可变参数的使用
      • css样式文件该放在哪里
      • php中数组下标必须是连续的吗
      • Python 3 教程
        Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
        Python 3 教程
      • Python pip包管理
        一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
        Python pip包管理
      • ubuntu如何重新编译内核
      • 改善Java代码之慎用java动态编译

      目录