C++中类的相关学习

news2024/9/28 11:19:30

动态内存分配和回收(堆区)

C语言中动态内存分配和回收使用malloc函数和free函数完成的

C++依旧可以使用上述的两个函数完成,动态内存分配和回收

C++也可以使用两个关键字new和delete来完成动态内存的分配和回收

内存分配

单个申请

格式:数据类型 *指针名 = new 数据类型

int *p1 = new int;    //在堆区申请了int类型大小的空间,并将地址赋值给p1

例:

    //在堆区申请了int类型大小的空间,并将地址赋值给p1
    int *p1 = new int;
    cout << *p1 << endl;

    //在堆区申请了int类型大小的空间并初始化,然后将地址赋值给p1
    int *p2 = new int(100);
    cout << *p2 << endl;

连续申请

 //在堆区连续申请了5个int类型大小的空间,并将地址赋值给p1
    int *p1 = new int[5];
    for(int i=0;i<5;i++)
    {
        cin >> p1[i];
    }
    for(int j=0;j<5;j++)
    {
        cout << p1[j] << " ";
    }
    cout << endl;

内存回收(释放)

单个回收

格式:delete 指针名;

delete p1;

例:

    //在堆区申请了int类型大小的空间并初始化,然后将地址赋值给p1
    int *p2 = new int(100);
    cout << *p2 << endl;
    
    delete p2;
    p2 = nullptr;   //p2 = NULL;

连续回收

格式:delete []指针名;

delete []p2;

例:

    //在堆区连续申请了5个int类型大小的空间,并将地址赋值给p1
    int *p1 = new int[5];
    for(int i=0;i<5;i++)
    {
        cin >> p1[i];
    }
    for(int j=0;j<5;j++)
    {
        cout << p1[j] << " ";
    }
    cout << endl;
    delete []p1;
    p1 = nullptr;    //p1 = NULL

new,delete和malloc,free的区别(面试重点

new,delete

  1. 是关键字
  2. 申请空间以数据类型为单位
  3. 申请堆区空间是时可以初始化
  4. 申请什么类型的空间,指针就是什么类型
  5. 区分单个,连续的格式
  6. 申请对象空间时,会自动调用构造函数
  7. delete释放类对象空间时,会自动调用析构函数

malloc,free

  1. 是函数
  2. 申请空间以字节为单位
  3. 申请堆区空间时不能初始化
  4. 申请空间需要强转
  5. 不区分单个,连续的格式
  6. 申请对象空间时,不会自动调用构造函数
  7. free释放类对象空间时,不会自动调用析构函数

类中的特殊的成员函数

特殊的成员函数的种类:构造函数,析构函数,拷贝构造函数,拷贝赋值函数,移动构造,移动赋值,取地址符重载,常取地址符重载

特殊原因:

  • 这些函数无需程序员手动定义,系统会默认提供,如果程序员手动调用,那么系统就取消提供。
  • 这些函数无需手动调用,在特定的情况下会自动调用,即使是程序员手动定义的函数

构造函数

功能:

用类对象实例化一个对象时,会自动调用构造函数,给该对象申请空间和初始化使用的

格式:

函数名:与类同名

返回值:无,也无void

参数:可以有参数,可以无参数

访问权限:一般为public

类名(形参列表)
{
    函数体内容;
}

调用时机:

栈区

何时实例化对象,何时自动调用构造函

堆区

何时用new申请对象空间,合适自动调用构造函数

#include <iostream>

using namespace std;

class Student
{
private:
    string name;
    int age;
    string id;
public:
    void show()
    {
        cout << "名字: " << name << " 年纪:" << age << "  学号:" << id << endl;
    }

    //无参构造函数
    Student()
    {

        cout << "Student::无参构造函数" << endl;
    }

    //有参构造函数
    Student(string name,int age,string id)
    {
        this->name = name;
        this->age = age;
        this->id = id;
        cout << "Student::有参构造函数" << endl;
    }
};

int main()
{
    Student s1("zhang",10,"20200106133");
    s1.show();
    return 0;
}

系统默认提供的是无参构造函数,如果程序员手动定义,则系统取消默认提供,如果后期需要用到无参构造函数,则必须显性定义出来,否则报错。

可以给有参构造函数赋初始值。

初始化列表

构造函数的本身工作是完成类对象申请空间的,而初始化工作由初始化列表完成。

初始化列表由构造函数的形参小括号后由冒号引出

类名(形参1,形参2,形参3,...,形参n):成员变量1(形参1),成员变量2(形参2),成员变量3(形参3),..,成员变量n(形参n)
{
    函数体内容
}
#include <iostream>

using namespace std;

class Student
{
private:
    string name;
    int age;
    string id;
public:
    void show()
    {
        cout << "名字: " << name << " 年纪:" << age << "  学号:" << id << endl;
    }

    //无参构造函数
    Student()
    {

        cout << "Student::无参构造函数" << endl;
    }

    //有参构造函数
    Student(string name,int age,string id):name(name),age(age),id(id)
    {
        cout << "Student::有参构造函数" << endl;
    }
};

int main()
{
    Student s1("zhang",10,"20200106133");
    s1.show();
    return 0;
}

类的嵌套

#include <iostream>

using namespace std;

class Birthday
{
private:
    int year;
    int month;
    int day;
public:

    //无参构造函数
    Birthday()
    {
        cout << "Birethday::无参构造函数" << endl;
    }

    //有参构造函数
    Birthday(int year,int month,int day):year(year),month(month),day(day)
    {
        cout << "Birthday::有参构造函数" << endl;
    }
};

class Student
{
private:
    string name;
    int age;
    Birthday b;
public:
    //无参构造函数
    Student()
    {
        cout << "Student::无参构造函数" << endl;
    }

    //有参构造函数
    Student(string name,int age,int year,int month,int day):name(name),age(age),b(year,month,day)
    {
        cout << "Student::有参构造函数" << endl;
    }

};

int main()
{
    Student s1("zhang",24,2002,12,05);
    return 0;
}

析构函数

功能:

当类对象的生命周期结束后,会自动调用析构函数,来完成类对象的资源回收。

格式:

函数名:~类名

返回值:无返回值,也无void

参数:无参数

调用时机:

栈区:

类对象所在的函数结束,会自动调用析构函数

先构造的对象后析构(栈区先进后出)

堆区:

何时使用delete,何时自动调用析构函数

#include <iostream>

using namespace std;

class Cat
{
private:
    string name;
    string color;
public:
    //无参构造函数
    Cat()
    {
        cout << "Cat::无参构造函数" << endl;
    }

    //有参构造函数
    Cat(string n,string c):name(n),color(c)
    {
        cout << "Cat::有参构造函数" << endl;
    }

    //析构函数
    ~Cat()
    {
        cout << "Cat::析构函数" << endl;
    }
};

int main()
{
    Cat c1("zhang","black");
    Cat c2;
    return 0;
}

系统会默认提供一个析构函数,如果程序员手动定义,则系统取消默认提供

每个类中只能由一个析构函数。(原因:析构函数无参,不能重载)

当类中有指针成员时,并且该指针成员指向了堆区空间,此时需要将系统提供的析构函数显性定义出来,在析构函数中手动将指针成员申请的堆区空间释放,否则会导致内存泄漏

拷贝构造函数

功能:

拷贝构造函数是一种特殊的构造函数,用一个类对象给另一个类对象初始化使用的

格式:

函数名:类名

返回值:无返回值,无void

参数:同类的类对象

访问权限:一般为public

类名(const 类名 &other)
{
    函数体内容;
}

调用时机:

  • 用一个类对象给另一个类对象初始化使用的,自动调用拷贝构造函数
  • 当类对象作为函数的实参传递给形参的过程,自动调用拷贝构造函数
  • 当函数返回一个类对象的时,会自动调用拷贝构造函数

浅拷贝和深拷贝(重点

系统会默认提供一个拷贝构造函数,如果程序员手动定义,则系统取消默认提供。

系统提供的拷贝构造函数,是将一个对象的所有数据成员初始化另一个对象的所有数据成员,称为浅拷贝。

练习

 

设计一个Per类,类中包含私有成员:姓名、年龄、指针成员身高、体重,再设计一个Stu类,类中包含私有成员:成绩、Per类对象p1,设计这两个类的构造函数、析构函数和拷贝构造函数。

#include <iostream>

using namespace std;

class Par
{
private:
    string name;
    int age;
    int *height;
    int *weight;
public:
    //无参构造函数
    Par()
    {
        cout << "Par::无参构造函数" << endl;
    }

    //有参构造函数
    Par(string n,int a,int h,int w):name(n),age(a),height(new int(h)),weight(new int(w))
    {
        cout << "Par::有参构造函数" << endl;
    }

    //析构函数
    ~Par()
    {
        cout << "Par::析构函数" << endl;
    }

    //拷贝构造函数
    Par(const Par &other):name(other.name),age(other.age),height(new int(*(other.height))),weight(new int(*(other.weight)))
    {
        cout << "Par:拷贝构造函数" << endl;
    }
};

class Stu
{
private:
    int score;
    Par p1;
public:
    //无参构造函数
    Stu()
    {
        cout << "Stu::无参构造函数" << endl;
    }

    //有参构造函数
    Stu(int s,string n,int a,int h,int w):score(s),p1(n,a,h,w)
    {
        cout << "Stu::有参构造函数" << endl;
    }

    //析构函数
    ~Stu()
    {
        cout << "Stu::析构函数" << endl;
    }

    //拷贝构造函数
    Stu(const Stu &other):score(other.score),p1(other.p1)
    {
        cout << "Stu:拷贝构造函数" << endl;
    }

};

int main()
{
    Par p0;
    Par p("zhang",24,64,180);
    Par p1 = p;

    Stu s0;
    Stu s(98,"zhang",24,64,180);
    Stu s1 = s;
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2089053.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Chapter 07 watch侦听器

欢迎大家订阅【Vue2Vue3】入门到实践 专栏&#xff0c;开启你的 Vue 学习之旅&#xff01; 文章目录 前言一、基本用法二、深度侦听 前言 在 Vue 中&#xff0c;watch 侦听器是一个非常实用的工具&#xff0c;用于处理自定义数据的变化。本文详细讲解了 watch 侦听器的基本用法…

Pytorch实现多层LSTM模型,并增加emdedding、Dropout、权重共享等优化

简述 本文是 Pytorch封装简单RNN模型&#xff0c;进行中文训练及文本预测 一文的延申&#xff0c;主要做以下改动&#xff1a; 1.将nn.RNN替换为nn.LSTM&#xff0c;并设置多层LSTM&#xff1a; 既然使用pytorch了&#xff0c;自然不需要手动实现多层&#xff0c;注意nn.RNN…

JVM1-初识JVM

目录 什么是JVM JVM的功能 解释和运行 内存管理 即时编译 Java性能低的主要原因和跨平台特性 常见的JVM 什么是JVM JVM 全称是 Java Virtual Machine&#xff0c;中文译名&#xff1a;Java虚拟机 JVM本质上是一个运行在计算机上的程序&#xff0c;它的职责是运行Java字…

AI大模型编写多线程并发框架(六十三):监听器优化·下

系列文章目录 文章目录 系列文章目录前言一、项目背景二、第十一轮对话-修正运行时数据三、修正任务计数器四、第十二轮对话-生成单元测试五、验证通过七、参考文章 前言 在这个充满技术创新的时代&#xff0c;AI大模型正成为开发者们的新宠。它们可以帮助我们完成从简单的问答…

C++,如何写单元测试用例?

文章目录 1. 概述1.1 什么是单元测试&#xff1f;1.2 为什么要做单元测试&#xff1f; 2. 写测试用例的方法3. 编写测试用例的通用原则3.1 目的性原则3.2 独立性原则3.3 可重复性原则3.4 小规模原则3.5 一致性原则3.6 自动化原则3.7 边界条件原则3.8 错误检测原则3.9 性能原则3…

西门子PLC控制激光读头,profient转Ethernet IP网关应用

在智能制造的浪潮下&#xff0c;企业对于生产线的灵活性、智能化水平以及数据交互能力提出了更高要求。西门子PLC以其高可靠性和丰富的功能模块&#xff0c;广泛应用于各种自动化生产线中。而激光读头作为精密测量与定位的关键设备&#xff0c;其高精度、非接触式测量特性在自动…

力扣862.和至少为K的最短子数组

力扣862.和至少为K的最短子数组 双端单调队列 前缀和 用单调队列存遍历过的前缀和&#xff0c;同时两个优化 1. 2. class Solution {public:int shortestSubarray(vector<int>& nums, int k) {int n nums.size(),ans n 1;long s[n1];s[0] 0L;for(int i0;i…

1999-2023年上市公司年报文本数据(PDF+TXT)

1999-2023年上市公司年报文本数据&#xff08;PDFTXT&#xff09; 1、时间&#xff1a;1999-2023年 2、来源&#xff1a;上市公司年度报告 3、范围&#xff1a;A股上市公司&#xff0c;5600企业&#xff0c;6.3W份 4、格式&#xff1a;PDFTXT 5、下载链接&#xff1a; 199…

东方通Web服务器(TongWeb)控制台部署改自动部署操作

首先将控制台部署改自动部署的应用进行解除部署&#xff0c;具体如下&#xff1a;登录TongWeb管理控制台&#xff0c;在左侧导航栏中点击“应用管理”&#xff0c;通过应用列表中第一列复选框选中要解除部署的应用&#xff0c;点击“解部署”&#xff0c;完成应用解除部署操作。…

4.Copy Constructor的构造操作

目录 1、对象赋值问题引入 2、Bitwise Copy Semantics&#xff08;位逐次拷贝&#xff09; 3、处理class virtual function 4、处理virtual base class subobject 1、对象赋值问题引入 在C中&#xff0c;有三种情况会以一个object的内容作为另一个class object的初值。这三…

Upload-labs靶场通过攻略

pass-01 1.写一个一句话木马 2.上传php文件 当我们上传php文件时 提示文件类型不正确 3.修改php后缀 通过修改php后缀为jpg 抓包再次修改成php文件 4.查看是否上传成功 页面显示图片 表示上传成功 pass-02 1.上传一个php文件 页面显示文件类型不正确 2.抓包修改 可以看…

【Python零基础】文件使用和异常处理

文章目录 前言一、从文件中读取数据二、向文件中写入数据三、异常四、存储数据总结 前言 本篇笔者将展示Python如何处理文件数据&#xff0c;包括文件内容的读取和写入操作&#xff0c;以及程序运行时异常模块的处理方式&#xff0c;保证我们写出健壮的代码。 一、从文件中读取…

Nature揭示应变不变的射频电子器件新突破,无线健康监测的前景

【行业背景】 可拉伸电子设备是未来柔性电子技术发展的重要趋势。这些设备在皮肤接口、健康监测、智能穿戴等领域发挥着关键作用&#xff0c;离不开高性能的射频&#xff08;RF&#xff09;电子组件。射频电子设备的功能依赖于其基板材料的电气性能&#xff0c;然而传统的弹性…

突发:Runway 从 HuggingFace 上删库跑路,究竟发生了什么?

&#x1f525; 突发新闻&#xff1a;Runway 从 HuggingFace 上删库跑路&#xff0c;究竟发生了什么&#xff1f; 1️⃣ Runway 从 HuggingFace 上删库跑路&#xff01;究竟是技术问题还是另有隐情&#xff1f; 最近科技圈内流传着一则令人瞠目结舌的消息&#xff1a;曾经为AI图…

5款自动生成文案的神器,助你轻松创作优质文案

随着人工智能技术的发展&#xff0c;生活中的很多工作都可以自动化操作&#xff0c;就连创作文案也不再会让人绞尽脑汁的去思考怎么写&#xff0c;因为有了自动生成文案的神器&#xff0c;从而使创作者在写作文案的过程中更加得心应手&#xff0c;并且不费吹灰之力便能拥有优质…

优思学院|精益生产中现场管理的7大工具

在现代制造业中&#xff0c;精益生产&#xff08;Lean Production&#xff09;已成为提升生产效率、确保产品质量的关键方法论。精益生产的核心思想在于消除浪费、持续改进&#xff0c;而要实现这些目标&#xff0c;依赖于一系列行之有效的管理工具。在这篇文章中&#xff0c;我…

爆品是测出来的,不是选出来的

我在亚马逊摸爬滚打了五年&#xff0c;深深感受到了"七分选品&#xff0c;三分运营"的重要性。不管你的产品图片、描述多么精美&#xff0c;如果不去精选和测试&#xff0c;很难保证能出单。我见过很多跨境新手在选品上卡了几个月&#xff0c;纠结于卖什么。但实际上…

一次VUE3 使用axios调用萤石云OpenAPI踩坑经历

通过调用萤石云的获取设备列表功能&#xff0c;我们可以根据 ACCESS_TOKEN 获取该用户下的设备列表。 Python 调用接口 根据接口文档[1]&#xff0c;使用Python&#xff0c;很轻松就能获取到该列表&#xff0c;代码如下&#xff08;该代码用于拼接生成vue代码&#xff0c;这是…

爱浦路云化核心网:支持百万用户规模,构筑超快海量连接网络

广州爱浦路网络技术有限公司&#xff08;简称&#xff1a;IPLOOK&#xff09;是全球领先的4G/5G/6G核心网厂商&#xff0c;致力于向全球客户提供端到端的移动通信解决方案&#xff0c;其产品和服务覆盖了卫星通信、能源通信、电网通信等多个重要领域。经过十二年的探索与发展&a…

英文论文格式编辑(二)

这里写自定义目录标题 正文部分段落格式段落对齐方式conclusion图片左右对齐 正文部分段落格式 出现下面这种箭头&#xff0c;是使用了标题格式 在这个样式里面修改 包括图片啥的&#xff0c;都别用标题格式&#xff0c;按道理来说&#xff0c;一个标题的箭头是能把下面的内…