C++基础——构造函数

当我们创建对象的时候,这个对象应该有一个初始状态,当对象销毁之前应该销毁自己创建的一些数据。对象的初始化和清理也是两个非常重要的安全问题,一个对象或者变量没有初始时,对其使用后果是未知,同样的使用完一个变量,没有及时清理,也会造成一定的安全问题。c++为了给我们提供这种问题的解决方案,构造函数析构函数,这两个函数将会被编译器自动调用,完成对象初始化和对象清理工作。

一、构造函数

构造函数主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。

用一个例子来说明:

class Person{
public:Person(){cout << "构造函数调用!" << endl;pName = (char*)malloc(sizeof("John"));strcpy(pName, "John");mTall = 150;mMoney = 100;}
public:char* pName;int mTall;int mMoney;
};void test(){Person person;cout << person.pName << person.mTall << person.mMoney << endl;
}

Person为构造函数,对pName,mTall,mMoney进行初始化。

二、构造函数的分类

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

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

class Person{
public:Person(){cout << "no param constructor!" << endl;mAge = 0;}//有参构造函数Person(int age){cout << "1 param constructor!" << endl;mAge = age;}//拷贝构造函数(复制构造函数) 使用另一个对象初始化本对象Person(const Person& person){cout << "copy constructor!" << endl;mAge = person.mAge;}//打印年龄void PrintPerson(){cout << "Age:" << mAge << endl;}
private:int mAge;
};
//1. 无参构造调用方式
void test01(){//调用无参构造函数Person person1; person1.PrintPerson();//无参构造函数错误调用方式//Person person2();//person2.PrintPerson();
}
//2. 调用有参构造函数
void test02(){//第一种 括号法,最常用Person person01(100);person01.PrintPerson();//调用拷贝构造函数Person person02(person01);person02.PrintPerson();//第二种 匿名对象(显示调用构造函数)Person(200); //匿名对象,没有名字的对象Person person03 = Person(300);person03.PrintPerson();//注意: 使用匿名对象初始化判断调用哪一个构造函数,要看匿名对象的参数类型Person person06(Person(400)); //等价于 Person person06 = Person(400);person06.PrintPerson();//第三种 =号法 隐式转换Person person04 = 100; //Person person04 =  Person(100)person04.PrintPerson();//调用拷贝构造Person person05 = person04; //Person person05 =  Person(person04)person05.PrintPerson();
}

注意:不能调用拷贝构造函数去初始化匿名对象

三、拷贝函数调用时机

  1. 对象以值传递的方式传给函数参数对象时调用拷贝构造
  2. 函数局部对象以值传递的方式从函数返回(vs debug模式下调用一次拷贝构造,qt不调用任何构造)
  3. 用一个对象初始化另一个对象时调用拷贝构造
class Person{
public:Person(){cout << "no param contructor!" << endl;mAge = 10;}Person(int age){cout << "param constructor!" << endl;mAge = age;}Person(const Person& person){cout << "copy constructor!" << endl;mAge = person.mAge;}~Person(){cout << "destructor!" << endl;}
public:int mAge;
};
//1. 旧对象初始化新对象
void test01(){Person p(10);Person p1(p);Person p2 = Person(p);Person p3 = p; // 相当于Person p2 = Person(p);
}//2. 传递的参数是普通对象,函数参数也是普通对象,传递将会调用拷贝构造
void doBussiness(Person p){}void test02(){Person p(10);doBussiness(p);
}//3. 函数返回局部对象
Person MyBusiness(){Person p(10);cout << "局部p:" << (int*)&p << endl;return p;
}
void test03(){//vs release、qt下没有调用拷贝构造函数//vs debug下调用一次拷贝构造函数Person p = MyBusiness();cout << "局部p:" << (int*)&p << endl;
}

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

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

相关文章

微信小程序开发实战:运动数据轻松获取,让健康生活触手可及【代码示例】

微信小程序开发实战&#xff1a;运动数据轻松获取&#xff0c;让健康生活触手可及【代码示例】 基础概念与API介绍微信运动数据接口权限申请 实战步骤1. 配置权限2. 请求用户授权3. 解密运动数据4. 后端解密逻辑 安全性与性能优化结语与讨论 在移动互联网时代&#xff0c;健康管…

AcWing 827. 双链表——算法基础课题解

AcWing 827. 双链表 题目描述 实现一个双链表&#xff0c;双链表初始为空&#xff0c;支持 5 种操作&#xff1a; 在最左侧插入一个数&#xff1b;在最右侧插入一个数&#xff1b;将第 k 个插入的数删除&#xff1b;在第 k 个插入的数左侧插入一个数&#xff1b;在第 k 个插…

【Github】直接引用Github仓库中的图片

用picgo能够上传图片、复制链接。 那如果我已经将图片通过其他方法上传到Github仓库中&#xff0c;难道还要上传一次&#xff1f; 不用&#xff01; 步骤 1.打开仓库中要访问的图片 2.复制此时浏览器链接: https://github.com/jaxhur/image/blob/main/image-2022082410480713…

Navicat连接远程服务器的MySQL(局域网)

Navicat如何连接远程服务器的MySQL_navicat远程连接mysql-CSDN博客 我的电脑上运行MySQL的服务器端 正好在我哥家&#xff0c;在他的电脑上安装Navicat 两台电脑连接他家的wifi&#xff0c;那么就是处在同一局域网中&#xff0c;把防火墙都关掉&#xff0c;可以互相ping通。…

elementUi中的el-table合计行添加点击事件

elementUi 文档中&#xff0c;合计行并没有点击事件&#xff0c;这里自己实现了合计行的点击事件。 created() {this.propertyList [{ property: order, label: 序号 },{ property: deptName, label: 单位名称 },{ property: contentPublishQuantity, label: 文章数量 },{ pro…

解锁WSL下Docker使用

简介&#xff1a;Windows Subsystem for Linux&#xff08;简称WSL&#xff09;是一个在Windows 10上能够运行原生Linux二进制可执行文件&#xff08;ELF格式&#xff09;的兼容层。正常情况下&#xff0c;WSL安装完成后直接使用docker会抛出以下报错&#xff1a; Cannot conn…

谷歌推广和seo留痕具体怎么操作?

留痕跟谷歌推广其实是一回事&#xff0c;你能在谷歌上留痕&#xff0c;其实就是推广了自己的信息&#xff0c;本质上留痕就是在各大网站留下自己的记录&#xff0c;这个记录可以是品牌信息&#xff0c;联系方式&#xff0c;看你想留下什么 如果要问自己怎么操作&#xff0c;正常…

微信公众号排名 SEO的5个策略

随着微信公众号在社交媒体领域的持续发展和普及&#xff0c;如何提升公众号的搜索排名&#xff0c;成为许多运营者关注的焦点。公众号排名SEO&#xff0c;即针对微信公众号进行搜索引擎优化&#xff0c;旨在提高公众号在搜索结果中的曝光率和点击率。下面&#xff0c;我们将深入…

数据库中虚拟表和临时表的区别?

虚拟表&#xff08;Virtual Table&#xff09;和临时表&#xff08;Temporary Table&#xff09;在数据库系统中都用于处理暂时性的数据存储需求&#xff0c;但它们的概念和用途有所不同&#xff1a; 虚拟表&#xff08;通常是视图View&#xff09;&#xff1a; 虚拟表&#…

银行电子凭证技术规范

银行电子凭证技术规范 1 范围 本文件规定了银行电子凭证的文件、数据与样式、系统逻辑框架、生成、通信传输和安全要求&#xff0c;以 及验证方法。 本文件适用于银行电子凭证数据实例与版式文件的开具、传输、接收和应用。 2 规范性引用文件 下列文件中的内容通过文中的规范…

如何复制本地docker镜像到其他主机

&#xff08;1&#xff09;打包镜像 比如我要复制的镜像是grafana的镜像 docker images 这里我把打包的镜像放在了根~目录下&#xff0c;如截图所示&#xff1a; docker save grafana/grafana:latest -o ~/grafana.jar &#xff08;2&#xff09;移动镜像 scp命令拷贝镜像到目标…

标贝数据采集标注在自动驾驶场景中落地应用实例

AI数据服务作为人工智能和机器学习的基础&#xff0c;在自动驾驶领域中有着重要地位。与其他人工智能应用场景相比&#xff0c;自动驾驶的落地场景相对复杂&#xff0c;想要让汽车本身的算法做到处理更多、更复杂的场景&#xff0c;就需要运用大量场景化高质量AI数据做支撑。标…

kafka日志存储

前言 kafka的主题(topic)可以对应多个分区(partition)&#xff0c;而每个分区(partition)可以有多个副本(replica)&#xff0c;我们提生产工单创建topic的时候也是要预设这些参数的。但是它究竟是如何存储的呢&#xff1f;我们在使用kafka发送消息时&#xff0c;实际表现是提交…

uniapp遍历数组对象的常见方法

在 UniApp 中&#xff0c;遍历数组对象的方法与在普通 JavaScript 中是相同的。UniApp 是一个使用 Vue.js 开发所有前端应用的框架&#xff0c;因此你可以使用 Vue.js 和 JavaScript 的语法来遍历数组对象。 以下是一些常见的遍历数组对象的方法&#xff1a; 使用 for 循环 …

解密MySQL之谜:为何B+树胜过跳表成为其首选索引结构?

在数据库系统中&#xff0c;索引是提高查询性能的关键因素之一。MySQL 作为最流行的关系型数据库管理系统之一&#xff0c;其底层存储引擎使用的索引结构主要是 B 树。 然而&#xff0c;跳表作为一种高效的数据结构&#xff0c;在某些情况下也能够提供较好的查询性能。 为什么…

tomcat-GC溢出

背景 一个项目需要导出大量的数据&#xff0c;导致GC但是这个项目在本地能够运行&#xff0c;但是在服务器上就不能运行本地和服务器的区别&#xff1a;NGINX和TOMCATGC和NGINX无关&#xff0c;那么就是Tomcat分配JVM的堆内存的容量不够 错误解决思路 网上教了一些查看JVM的大小…

分布式锁与秒杀

分布式锁与秒杀 1. 分布式锁1.1 常用Redis分布式锁方案三&#xff1a;使用Lua脚本(包含SETNX EXPIRE两条指令) 秒杀 1. 分布式锁 https://www.cnblogs.com/shoshana-kong/p/17519673.html 1.1 常用Redis分布式锁方案三&#xff1a;使用Lua脚本(包含SETNX EXPIRE两条指令) …

sql注入基础-2

一、sqlmap工具(kali自带) 1、官网&#xff1a;http://www.sqlmap.org 2、版本查看 python sqlmap.py --version 3、常见命令&#xff1a; -h&#xff1a;查看帮助信息-u "URL" &#xff1a;指定网站-p 参数1,参数2&#xff1a;指定参数 注&#xff1a;-p 只能跟…

力扣141.环形链表142.环形链表Ⅱ 附证明

题目链接&#xff1a; 141. 环形链表 - 力扣&#xff08;LeetCode&#xff09; 142. 环形链表 II - 力扣&#xff08;LeetCode&#xff09; 141.环形链表 方法思路&#xff1a;快慢指针 代码: class Solution { public:bool hasCycle(ListNode *head) {if(!head){return fa…

Nodejs内存管[Mark-Sweep算法][Mark-Compact]

内存控制 Mark-Sweep & Mark-Compact 对于老生代的对象&#xff0c;存活对象占较大的比重&#xff0c;采用scvenge方法会存在如下问题 1. 存活对象较多&#xff0c;复制存活对象的效率很低 2. 浪费一半空间的问题因此v8在老生代中主要采用了Mark-Sweep和Mark-Compact相结…