对象的构造

news2024/11/24 9:33:07

问题

对象中成员变量的初始值是多少?

成员变量的初始值

#include <stdio.h>

class Test
{
private:
    int i;
    int j;
public:
    int getI() { return i; }
    int getJ() { return j; }
};

Test gt;

int main()
{
    printf("gt.i = %d\n", gt.getI());
    printf("gt.j = %d\n", gt.getJ());
    
    Test t1;
    
    printf("t1.i = %d\n", t1.getI());
    printf("t1.j = %d\n", t1.getJ());
    
    Test* pt = new Test;
    
    printf("pt->i = %d\n", pt->getI());
    printf("pt->j = %d\n", pt->getJ());
    
    delete pt;
    
    return 0;
}

程序运行结果如下图所示

gt 变量是存储在静态存储区的,t1 变量是存储在栈上的,pt 变量是存储在堆上的,存储静态存储区变量的值初始值为0,存储在栈和堆上变量的初始值为随机值

从程序设计的角度,对象只是变量,因此:

在栈上创建变量时,成员变量初始值为随机值

在堆上创建变量时,成员变量初始值为随机值

在静态存储区创建变量时,成员变量初始值为 0

构造函数

C++ 中可以定义与类名相同的特殊成员函数

这种特殊的成员函数叫做构造函数

构造没有任何返回类型的声明

构造函数在对象定义时自动被调用

构造函数初探

#include <stdio.h>

class Test
{
private:
    int i;
    int j;
public:
    int getI() { return i; }
    int getJ() { return j; }
    Test()
    {
        printf("Test() Begin\n");
        
        i = 1;
        j = 2;
        
        printf("Test() End\n");
    }
};

Test gt;

int main()
{
    printf("gt.i = %d\n", gt.getI());
    printf("gt.j = %d\n", gt.getJ());
    
    Test t1;
    
    printf("t1.i = %d\n", t1.getI());
    printf("t1.j = %d\n", t1.getJ());
    
    Test* pt = new Test;
    
    printf("pt->i = %d\n", pt->getI());
    printf("pt->j = %d\n", pt->getJ());
    
    delete pt;
    
    return 0;
}

代码运行结果如下图所示

我们创建了 3 个 Test 对象,通过打印可以看出 Test 构造函数被调用了三次;每创建一个类对象,这个类的构造函数就会被自动调用

带有参数的构造函数

构造函数可以根据需要定义参数

一个类中可以存在多个重载的构造函数

构造函数的重载遵循 C++ 重载的规则

对象定义和对象声明不同

对象定义:申请对象的空间,并调用构造函数

对象声明:告诉编译器存在这样一个对象

构造函数的自动调用

带参数的构造函数

#include <stdio.h>

class Test
{
public:
    Test() 
    { 
        printf("Test()\n");
    }
    Test(int v) 
    { 
        printf("Test(int v), v = %d\n", v);
    }
};

int main()
{
    Test t;      // 调用 Test()
    Test t1(1);  // 调用 Test(int v)
    Test t2 = 2; // 调用 Test(int v)
    
    int i(100);
    
    printf("i = %d\n", i);
    
    return 0;
}

程序运行结果如下图所示

第 18 行调用的是不带参数的构造函数,第 19 20 行,调用的是带参数的构造函数 

构造函数的调用

一般情况下,构造函数在对象定义时被自动调用

一些特殊情况下,需要手工调用构造函数

需求:开发一个数组类解决原生数组的安全性问题

提供函数获取数组长度

提供函数获取数组元素

提供函数设置数组元素

两个特殊的构造函数

无参构造函数

  • 没有参数的构造函数
  • 当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且其函数体为空

拷贝构造函数

  • 参数为 const class_name& 的构造函数
  • 当类中没有定义拷贝构造函数时,编译器默认提供一个拷贝构造函数,简单的进行成员变量的值复制

拷贝构造函数的意义

兼容 C 语言的初始化方式

初始化行为能够符合预期的逻辑

深拷贝

  • 拷贝后对象的物理状态相同

浅拷贝

  • 拷贝后对象的逻辑状态相同

编译器提供的拷贝构造函数只进行浅拷贝!

什么时候需要进行深拷贝?

对象中有成员指代了系统中的资源

成员指向了动态内存空间

成员打开了外存中的文件

成员使用了系统中的网络端口

问题分析

一般性原则

自定义拷贝构造函数,必然需要实现深拷贝!!!

小结

每个对象在使用之前都应该初始化

类的构造函数用于对象的初始化

构造函数与类同名并且没有返回值

构造函数在对象定义时自动被调用

构造函数可以根据需要定义参数

构造函数之间可以存在重载关系

构造函数遵循 C++ 中重载函数的规则

在一些情况下可以手动调用构造函数

C++ 编译器会默认提供构造函数

无参构造函数用于定义对象的默认初始化状态

拷贝构造函数在创建对象时拷贝对象的状态

对象的拷贝有浅拷贝和深拷贝两种

  • 浅拷贝使得对象的逻辑状态相同
  • 深拷贝使得对象的物理状态相同

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

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

相关文章

UE中使用Editor Utility Widget创建编辑器工具

在UE中可以使用EditorUtilityWidget创建编辑器面板工具&#xff0c;方便平时的开发。在UE4中使用编辑器UI需要开启对应插件&#xff0c;而UE5中则默认启用&#xff0c;下面就来学习一下。 1.UI创建 1.1.在Content Browser中右键&#xff0c;找到Editor Utilities即可创建编辑…

[MySQL]不允许你不会SQL语句之查询语句

&#x1f3ac; 博客主页&#xff1a;博主链接 &#x1f3a5; 本文由 M malloc 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f384; 学习专栏推荐&#xff1a;LeetCode刷题集&#xff01; &#x1f3c5; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指…

分享几个AI绘图的学习网址

AI绘图是一种使用人工智能技术来创建图形和图像的技术。 从技术角度来看&#xff0c;AI绘图是一个非常有趣和不断发展的领域。随着人工智能技术的不断进步&#xff0c;AI绘图也在不断地发展和创新&#xff0c;现在已经成为数字艺术领域中的一个重要分支。 AI绘图的出现也为许多…

2023年的深度学习入门指南(17) - 深度学习的硬件加速技术

2023年的深度学习入门指南(17) - 深度学习的硬件加速技术 有了前面的知识之后&#xff0c;想必大家对于算力需求的理解已经越来越深刻了。 除了使用CPU&#xff0c;GPU这样的通用器件之外&#xff0c;采用专用的硬件来进行加速是一个大家都能想到的选择。 其中的代表器件就是…

Docke是什么,一文带你了解

Docker的优势、与虚拟机技术的区别、三个重要概念和架构及工作原理详细讲解 随着云计算和容器化技术的发展&#xff0c;Docker作为一种轻量级的容器化技术&#xff0c;受到了越来越多的关注和应用。本文将详细介绍Docker的优势、与虚拟机技术的区别、三个重要概念和架构及工作…

memcpy 和 memmove的模拟实现

文章目录 1.函数的介绍 2.模拟实现 文章内容 1.函数的介绍 memcpy指的是C和C使用的内存拷贝函数&#xff0c;函数原型为void *memcpy(void*dest,void*src, size_t count)&#xff1b;函数的功能是从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中&#xff0c;即从…

内网穿透(NAT 穿透)原理+工具(部分无需管理员权限)

内网穿透&#xff0c;即 NAT&#xff08;Network Address Translation&#xff09; 穿透 内网穿透的实质是内网映射&#xff0c;内网地址转换成外网地址的实现。实现过程要有端对端数据传输&#xff0c;也有端口转发原理。内网映射方式&#xff0c;可以解决无公网IP问题&#…

Android问题笔记-Android studio 出现Failed to compile values file.错误

点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&…

docker compose 容器编排工具

目录 docker compose是什么&#xff1f; 官网网站&#xff1a;Docker Compose overview | Docker Documentation 安装使用compose&#xff1a; 步骤&#xff1a; 1、下载并安装compose的命令行插件 2、安装完成后授予权限&#xff0c;测试compose是否可以使用 3、实例测试…

AI大模型迈入应用时代,每日互动推动“可控大模型”落地

垂直行业更需要可控大模型 当下&#xff0c;大模型正在不断精进&#xff0c;以GPT-4、文心一言为代表的大模型&#xff08;LLM&#xff09;表现出了强大的逻辑推理能力&#xff0c;并能够很好地处理复杂任务&#xff0c;使得社会生产力得到了飞跃式提升。 面对大模型热度的持…

全网最详细,自动化测试与自动化框架总结,你不知道的都在这了...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 单元测试框架 单…

网络:IP地址、子网掩码、网络地址、广播地址、网段、网关

目录 一、IP地址 二、子网掩码 三、网络地址 四、广播地址 五、网段 六、网关 七、IP地址、子网掩码、网络地址、广指地址、网殷、网关的关系 参考链接 一、IP地址 IP地址是因特网协议&#xff08;IP&#xff09;中使用的一种数字标识符&#xff0c;用于唯一地标识网络…

LLM - 基于 Vicuna-13B 参数计算搭建私有 ChatGPT 在线聊天

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://blog.csdn.net/caroline_wendy/article/details/131312366 LLaMA 和 Vicuna 都是大语言模型(LLM)&#xff0c;两者的差异如下&#xff1a; LLaMA (Large Language Model Meta AI)&#…

英飞凌MCU芯片选型推荐参考

前言: 英飞凌Infineon作为一家芯片大厂,有众多芯片产品可供选型,这里重点推荐下庞大的MCU系列如何选项。首先,对于英飞凌产品构成要有深刻的认识,需要熟悉一个半导体产业并购的历程。2013年5月,Spansion 1.1亿美元并购了对富士通(Fujitsu)半导体微控制器和模拟业务部门…

聚类Clustering方法定位船舶站点

背景 现有船舶的航线中采样的数据库&#xff0c;采样的总时长为3个月&#xff0c;仅采样航速静止&#xff08;小于1节&#xff09;的数据&#xff0c;关键有效数据主要有经纬度/实时吃水量。 思路 基于站点附近轮船有停靠且航行速度慢&#xff0c;故取样点多的基础认识&…

正确的认识泥石流以及做好泥石流的防范

泥石流是山区沟谷中由暴雨、冰雪融水或地下含水层的渗入所形成的携带大量泥沙、石块等固体物质的特殊洪流&#xff0c;具有流量大、历时短、破坏力强等特征&#xff0c;泥石流携带的泥沙、石块等可高达数十米&#xff0c;并从山坡上倾泻而下&#xff0c;往往会形成一个“堰塞湖…

Python自动化测试利器selenium详解

Selenium是一种常用的Web自动化测试工具&#xff0c;支持多种编程语言和多种浏览器&#xff0c;可以模拟用户的交互行为&#xff0c;自动化地执行测试用例和生成测试报告。Selenium基于浏览器驱动实现&#xff0c;结合多种定位元素的方法&#xff0c;可以实现各种复杂的Web应用…

二进制搭建Kubernetes集群(一)——部署etcd集群和单master

单master集群架构图&#xff1a; 实验环境&#xff08;二进制搭建 Kubernetes v1.20&#xff09; 注意&#xff1a;生产环境中&#xff0c;etcd集群和master、node节点都应该部署在不同的机器上&#xff0c;此处为了实验方便&#xff0c;将三台etcd节点分别部署在了master和no…

探究Vue源码:mustache模板引擎(3) 通过编写简单正则了解mustache转换思路

我们会基本使用显然不够啊 我们要去了解mustache的原理 乃至自己去写一个mustache 首先 mustache 不是不能用简单的正则表达式来实现 但是 这里为了让大家理解 为什么不能 我们还是用简单正则写一下 我们创建一个 html文件 然后 编写代码如下 <!DOCTYPE html> <htm…

API性能监控 【ApiHelp】-- 组件Monitor 核心功能实现

上篇文章介绍了组件Monitor主要设计和功能Monitor组件设计&#xff0c;现在来具体看看Monitor组件的实现。 1、Java Agent实现AgentMain 前面已经介绍了Java Agent相关知识&#xff0c;现在来具体实现下。 实现AgentMain类&#xff1a; AgentMain为agent的入口类&#xff0c;程…