对象的构造和析构

news2025/1/22 19:00:32

目录

构造函数和析构函数

构造函数的分类和调用

c++默认构造的函数

浅拷贝和深拷贝

多个对象的构造和析构

初始化列表

类对象作为成员


构造函数和析构函数

对象的初始化和清理是两个非常重要的安全问题,一个对象或者变量没有初始时,对其使用后果是未知,同样的使用完一个变量,没有及时清理,也会造成一定的安全问题。c++为了给我们提供这种问题的解决方案,构造函数和析构函数,这两个函数将会被编译器自动调用,完成对象初始化和对象清理工作。
构造函数主要作用在于 创建对象 时为对象的成员属性赋值
析构函数主要用于 对象销毁 前系统自动调用,执行一些清理工作。
#include <iostream>
#include <string.h>

using namespace std;

class function
{
    public:
        //构造函数 函数名和类名相同,没有返回值,不能有void,但可以有参数 可以重载
        function(int init_age,string init_name)
        {
            age = init_age;
            name = init_name;
            cout << "构造函数调用" << endl;
        }
        //析构函数 函数名是在类名前面加”~”组成,没有返回值,不能有void,不能有参数,不能重载
        ~function()
        {
            cout << "析构函数调用" << endl;
        }
    public:
        int age;
        string name;
};

void test()
{
    function p1(10,"lucy");//构造函数在实例化对象时会创建,就是在内存开辟空间时会被调用
    //定义在栈区 test生命周期结束后会被销毁 在销毁之前自动调用析构函数 
}

int main()
{
    test();
    return 0;
}

编译运行

构造函数的分类和调用

按参数类型:分为无参构造函数和有参构造函数

按类型分类:普通构造函数和拷贝构造函数(复制构造函数)

拷贝构造:拷贝构造的调用时机:旧对象初始化新对象

                  其形参必须是引用,但并不限制为const,一般普遍的会加上const限制

                  如果自定义了一个拷贝构造 那么系统不再提供默认的拷贝构造

#include <iostream>
#include <string.h>

using namespace std;

class function
{
    public:  
        function()
        {
            cout << "无参构造函数" << endl;
        }

        function(int init_age,string init_name)
        {
            age = init_age;
            name = init_name;
            cout << "有参构造函数" << endl;
        }
        //拷贝构造的调用时机:旧对象初始化新对象
        //如果自定义了一个拷贝构造 那么系统不再提供默认的拷贝构造
        function(const function &p)//不能写function p 不能产生新对象 
        {
            //拷贝构造做了简单的值拷贝
            age = p.age;
            name = p.name;
            cout << "拷贝构造" << endl;
        }
        ~function()
        {
            cout << "析构" << endl;
        }

    public:
        int age;
        string name;
};

void test01()
{
    //如果人为提供了一个有参或无参构造 系统将不再提供默认的无参构造
    function p1;//调用无参构造时 不能加括号
    function p2(10,"lucy");
    function p3(p2);//调用系统提供的默认拷贝构造
}

void test02()
{
    //匿名对象 没有名字 生命周期在当前行
    function (10,"tom");
    function ();
    function p1(20,"ben");
    //function p2(p); //匿名对象不能使用括号法调用拷贝函数
}
//显示法调用构造函数
void test03()
{
    function p1 =  function (10,"tom");//显示法调用有参函数 
    function p2 =  function (p1); //显示法调用拷贝函数
    function p3 =  function ();//显示法调用无参函数

}

int main()
{
    test();
    return 0;
}

c++默认构造的函数

默认情况下,c++编译器至少为我们写的类增加 3 个函数

1.默认构造函数(无参,函数体为空)

2.默认析构函数(无参,函数体为空)

3.默认拷贝构造函数,对类中非静态成员属性简单值拷贝

如果用户定义拷贝构造函数, c++ 不会再提供任何默认构造函数
如果用户定义了普通构造 ( 非拷贝 ) c++ 不在提供默认无参构造,但是会提供默认拷贝构造

浅拷贝和深拷贝

浅拷贝:同一类型的对象之间可以赋值,使得两个对象的成员变量的值相同,两个对象仍然是独立的两个对象,这种情况 被称为浅拷贝. 一般情况下,浅拷贝没有任何副作用,但是当类中有指针,并且指针指向动态分配的内存空间,析构函数做了动 态内存释放的处理,会导致内存问题。

深拷贝:当类中有指针,并且此指针有动态分配空间,析构函数做了释放处理,往往需要自定义拷贝构造函数,自行给指针动态分配空间。

class Person{
    public:
        Person(char* name,int age){
            pName = (char*)malloc(strlen(name) + 1);
            strcpy(pName,name);
            mAge = age;
        }
        //增加拷贝构造函数
        Person(const Person& person){
            pName = (char*)malloc(strlen(person.pName) + 1);//重新开辟空间
            strcpy(pName, person.pName);
            mAge = person.mAge;
        }
        ~Person(){
            if (pName != NULL){
                free(pName);
            }
        }
    private:
        char* pName;
        int mAge;
};
void test(){
    Person p1("Edward",30);
    //用对象 p1 初始化对象 p2,调用 c++提供的默认拷贝构造函数
    Person p2 = p1;
}

多个对象的构造和析构

初始化列表

构造函数和其他函数不同,除了有名字,参数列表,函数体之外还有初始化列表。
初始化列表简单使用 :
class Person{
public :
        //传统方式初始化
        Person(int a,int b,int c)
        {
        mA = a;
        mB = b;
        mC = c;
        }
        //初始化列表方式初始化
        //先声明再根据声明的顺序定义初始化
        Person( int a, int b, int c):mA(a),mB(b),mC(c){}
        void PrintPerson()
        {
        cout << "mA:" << mA << endl;
        cout << "mB:" << mB << endl;
        cout << "mC:" << mC << endl;
        }
        private :
        int mA;
        int mB;
        int mC;
};

类对象作为成员

类中有多个对象时,构造的顺序是先构造里面的对象,再构造外面的对象

类中有多个对象时,析构的顺序是先析构外面的对象,再析构外面的对象

class Car{
    public:
        Car(){
            cout << "Car 默认构造函数!" << endl;
            mName = "大众汽车";
        }
        Car(string name){
            cout << "Car 带参数构造函数!" << endl;
            mName = name;
        }
        ~Car(){
            cout << "Car 析构函数!" << endl;
        }
    public:
        string mName;
};
//拖拉机
class Tractor{
    public:
        Tractor(){
            cout << "Tractor 默认构造函数!" << endl;
            mName = "爬土坡专用拖拉机";
        }
        Tractor(string name){
            cout << "Tractor 带参数构造函数!" << endl;
            mName = name;
        }
        ~Tractor(){
            cout << "Tractor 析构函数!" << endl;
        }
    public:
        string mName;
};
//人类
class Person{
    public:
        //类 mCar 不存在合适的构造函数
        Person(string name){
            mName = name;
        }
        //初始化列表可以指定调用构造函数
        Person(string carName, string tracName, string name) : mTractor(tracName),
        mCar(carName), mName(name){
            cout << "Person 构造函数!" << endl;
        }
#endif
        void GoWorkByCar(){
            cout << mName << "开着" << mCar.mName << "去上班!" << endl;
        }
        void GoWorkByTractor(){
            cout << mName << "开着" << mTractor.mName << "去上班!" << endl;
        }
        ~Person(){
            cout << "Person 析构函数!" << endl;
        }
    private:
        string mName;
        Car mCar;
        Tractor mTractor;
};
void test(){
    //Person person("宝马", "东风拖拉机", "赵四");
    Person person("刘能");
    person.GoWorkByCar();
    person.GoWorkByTractor();
}

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

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

相关文章

Ae 效果:CC Star Burst

模拟/CC Star Burst Simulation/CC Star Burst CC Star Burst&#xff08;CC 星爆&#xff09;可以模拟星际穿越的效果&#xff0c;也可以像 CC Ball Action 效果模拟球体的扩散运动。 CC Star Burst 效果的原理是将图层网格化&#xff0c;然后基于每个网格里的图层内容取平均颜…

【东软实训Day2】用Java实现客户端与服务器交互

一、客户端-服务器编程模型 1个应用 1个服务器进程 1…N个客户端进程&#xff0c;其中服务器管理资源&#xff0c;并通过操作这种资源为客户端服务。 客户端-服务器模型中的基本操作是事务&#xff08;transaction&#xff09;&#xff08;注&#xff1a;不同于数据库中的t…

软考-高级-信息系统项目管理第四版(完整24章全笔记)

《信息系统项目管理师教程》&#xff08;第4版&#xff09;是由全国计算机专业技术资格考试办公室组织编写的考试用书&#xff0c;根据2022年审定通过的《信息系统项目管理师考试大纲》编写&#xff0c;对信息系统项目管理师岗位所要求的主要知识及应用技术进行了阐述。 《信息…

ubuntu 20.04 通过 samba 共享文件夹到 windows

前言 ubuntu 与 windows 共享&#xff0c;有两条路&#xff0c;一是 windows 的目录共享给 ubuntu&#xff0c;比如使用 VM Ware 虚拟机&#xff0c;直接通过 VMWare 虚拟机共享文件夹的方式&#xff0c;windows 上的目录就共享给了 ubuntu ubuntu 如何把目录共享给 windows 呢…

zemax坐标断点实现光束偏移

简单来说就是将前面的坐标打断&#xff0c;实现新的坐标设置 基础设置&#xff1a; 对表面进行旋转&#xff1a; 系统自动插入坐标断点面 此时设置的旋转角度为0&#xff0c;我们将这个设置为变量&#xff1a; 在评价函数编辑器中选择REAY&#xff0c;控制光线高度 执行优化&a…

指针-矩阵变换

任务描述 给定一个矩阵&#xff0c;请编程将其按照以下约定的操作方式变换后输出。 相关知识 参考之前的关卡。 编程要求 根据提示&#xff0c;在右侧编辑器的Begin-End区域内补充代码。 测试说明 输入&#xff1a;第一行三个正整数 n&#xff0c;m 和 q 分别表示矩阵 A…

时间旅行的Bug 奇怪的输入Bug

故事一&#xff1a;时间旅行的Bug 在一个普通的工作日&#xff0c;程序员小明正在开发一个时间旅行的应用程序。这个应用程序可以让用户选择一个特定的日期和时间&#xff0c;然后将用户的意识传送到过去或未来的那个时刻。小明对这个项目非常兴奋&#xff0c;他认为这将是一个…

2023年9月8日

1> 自行封装一个栈的类&#xff0c;包含私有成员属性&#xff1a;栈的数组、记录栈顶的变量 成员函数完成&#xff1a;构造函数、析构函数、拷贝构造函数、入栈、出栈、清空栈、判空、判满、获取栈顶元素、求栈的大小 #include <iostream>using namespace std;class…

使用docker创建minio镜像并上传文件,提供demo

使用docker创建minio镜像并上传文件&#xff0c;提供demo 1. 整体描述2. 环境搭建2.1 windows环境搭建2.2 docker部署 3. spring集成3.1 添加依赖3.2 配置文件3.3 创建config类3.4 创建minio操作类3.5 创建启动类3.6 测试controller 4. 测试操作4.1 demo运行4.2 页面查看4.3 上…

GoogLeNet 08

一、发展 1989年&#xff0c;Yann LeCun提出了一种用反向传导进行更新的卷积神经网络&#xff0c;称为LeNet。 1998年&#xff0c;Yann LeCun提出了一种用反向传导进行更新的卷积神经网络&#xff0c;称为LeNet-5 AlexNet是2012年ISLVRC 2012&#xff08;ImageNet Large Sca…

[docker]笔记-存储管理

1、docker数据存储分为非永久性存储和永久性存储。 非永久性存储&#xff1a;容器创建会默认创建非永久性存储&#xff0c;该存储从属于容器&#xff0c;生命周期与容器相同&#xff0c;会随着容器的关闭而消失&#xff08;可理解为内存中数据&#xff0c;会随关机而消失&…

【jmeter】连接mysql无法使用executeQuery()

Can not issue data manipulation statements with executeQuery(). 翻译为&#xff1a; 在这里插入图片描述 看一下JDBC Request里的Query Type 改为Prepared Updata Statement&#xff0c;改完再试一下

CMake+CLion+Qt配置

在这里我下载MSVC的工具包&#xff0c;并没有下载Visual Studio。 配置编译环境 下载Visual Studio&#xff0c;其中有MSVC编译工具&#xff0c;下载MSVC工具包&#xff0c; 工具包下载链接&#xff1a;https://visualstudio.microsoft.com/zh-hans/visual-cpp-build-tools/ …

结构方程模型SEM、路径分析房价和犯罪率数据、预测智力影响因素可视化2案例...

原文链接&#xff1a;http://tecdat.cn/?p25044 在本文&#xff0c;我们将考虑观察/显示所有变量的模型&#xff0c;以及具有潜在变量的模型&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 1 简介 第一种有时称为“路径分析”&#xff0c;而后者有时称为“测…

2023国赛数学建模C题思路代码 - 蔬菜类商品的自动定价与补货决策

# 1 赛题 在生鲜商超中&#xff0c;一般蔬菜类商品的保鲜期都比较短&#xff0c;且品相随销售时间的增加而变差&#xff0c; 大部分品种如当日未售出&#xff0c;隔日就无法再售。因此&#xff0c; 商超通常会根据各商品的历史销售和需 求情况每天进行补货。 由于商超销售的蔬菜…

【Linux】工具Gdb调试轻度使用(C++)

目录 一、Gdb背景 二、Gdb基本命令 【2.1】list | l 【2.2】break | b 【2.5】delete | d 【2.6】disable 【2.7】enable 【2.3】info 【2.4】info locals 【2.6】run | r 【2.7】next | n 【2.8】step | s 【2.9】 continue | c 【2.10】bt 【2.11】finish 三…

idea报错“Static methods in interface require -target:jvm-1.8”

如题&#xff0c;在 idea 中跑 java 、scala 混编代码时&#xff0c;出现上面的错误。 问题的原因很明显是 idea 中的 jdk 版本设置有问题&#xff0c;针对性作如下排查&#xff1a; 检查项目的 java 版本 在File-> Project Settings中&#xff0c;检查检查idea的 java 版本…

SQL Server 跨库/服务器查询

这里写目录标题 1 SQL Server 跨库/服务器查询1.1 跨库查询1.2 跨服务器查询1.2.1 创建链接服务器1.2.2 跨库查询 1.3 拓展&#xff1a;SQL Server 中所有权和用户与架构的分离 1 SQL Server 跨库/服务器查询 1.1 跨库查询 在同一服务器下的跨库查询较为简单&#xff0c;示例…

QT Creator更改主题和编辑器风格(附几款黑色主题)

适用于qtcreator 一、使用自带主题与编辑器风格 打开Qt选择"工具"->"选项"&#xff1b; 2. 选择"环境"->"Theme"切换不同的主题风格 这里切换的是外边框的风格&#xff0c;如果编辑器中有同名的风格&#xff0c;编辑器的风格也…

【计算机基础知识9】前端设计模式与常见类型

目录 一、前言 二、设计模式的基本概念和原则 三、创建型设计模式 四、结构型设计模式 五、行为型设计模式 六、MVC和MVVM框架中的设计模式 七、实际应用案例分析 一、前言 在软件开发领域&#xff0c;设计模式是一种解决常见问题的最佳实践&#xff0c;它可以帮助开发…