对象的构造

news/2024/11/24 13:35:11/

问题

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

成员变量的初始值

#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.ppmy.cn/news/488237.html

相关文章

【Leetcode60天带刷】day20二叉树—— 654.最大二叉树 , 617.合并二叉树 , 700.二叉搜索树中的搜索 , 98.验证二叉搜索树

题目&#xff1a; 530. 二叉搜索树的最小绝对差 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等于两值之差的绝对值。 示例 1&#xff1a; 输入&#xff1a;root [4,2,6,1,3] 输出&#xff1…

android实现拍照、相册选图、裁剪功能,兼容7.0以及小米

现在一般的手机应用都会有上传头像的功能&#xff0c;我在实现这个功能的时候遇到很多问题&#xff0c;这里专门记录一下。 add 2018/5/10 21:05 先列举一下我出现过的问题&#xff1a; 1.运行时权限 2.调用系统相机拍照后crash&#xff0c;或者返回RESULT_CANCEL(0) 3.选择相…

Android 设备的CPU类型(通常称为”ABIs”)armeabiv-v7、arm64-v8a、armeabi、x86、x86_64之间的区别

一、各种类型的介绍 armeabiv-v7a&#xff1a;第7代及以上的 ARM 处理器。2011年15月以后的生产的大部分Android设备都使用它.arm64-v8a&#xff1a;第8代、64位ARM处理器&#xff0c;很少设备&#xff0c;三星 Galaxy S6是其中之一。armeabi&#xff1a;第5代、第6代的ARM处理…

Android 关于arm64-v8a、armeabi-v7a、armeabi、x86下的so文件兼容问题

引用: https://blog.csdn.net/ouyang_peng/article/details/51168072 armeabiv-v7a: 第7代及以上的 ARM 处理器。2011年15月以后的生产的大部分Android设备都使用它.arm64-v8a: 第8代、64位ARM处理器&#xff0c;很少设备&#xff0c;三星 Galaxy S6是其中之一。armeabi: 第5代…

android中的arm64-v8a、armeabi-v7a、armeabi、x86、x86_64下的so文件兼容问题

装了一款游戏在小米4上运行是ok的&#xff0c;在小米5上运行直接crash&#xff01; 原因&#xff1a;小米4系列采用的处理器为高通骁龙801&#xff0c;此款处理器是32位处理器。小米5系列则采用的是骁龙820 &#xff0c;是64位处理器。查看crash日志可以发现是是arm64-v8a文件…

小米开源AI框架mace编译构建

目录 简介 环境要求 1 安装 Bazel 2 安装Android NDK 3 在Ubuntu16.04下安装Docker&#xff08;17.09&#xff09; 构建并运行示例模型 1 拉取MACE项目 2 拉取MACE Model Zoo项目 3 构建通用MACE库 4 将预先训练的mobilenet-v2模型转换为MACE格式模型 编译运行DEMO…

arm64-v8a、armeabi-v7a、armeabi、x86 abiFilters 详解

abiFilters的作用 在app的gradle的defaultConfig里面加上如下 ndk {abiFilters "armeabi-v7a" // 指定要ndk需要兼容的架构(这样其他依赖包里mips,x86,armeabi,arm-v8之类的so会被过滤掉) } 指定要ndk需要兼容的架构(这样其他依赖包里mips,x86,armeabi,arm-v8之…

Android arm64-v8a、armeabi-v7a、armeabi详解

一、架构介绍 早期的Android系统几乎只支持ARMv5的CPU架构&#xff0c;后面发展到支持七种不同的CPU架构&#xff1a;ARMv5&#xff0c;ARMv7 (从2010年起)&#xff0c;x86 (从2011年起)&#xff0c;MIPS (从2012年起)&#xff0c;ARMv8&#xff0c;MIPS64和x86_64 (从2014年起…