C++自学笔记——动态创建对象

动态创建对象

1. 什么是动态创建对象?

在学习之前的知识点时,我们知道有静态存储期和自动存储期。 静态存储期的对象在程序的整个生命周期内都存在,全局变量和static修饰的局部变量都属于这一类。自动存储期的对象,这些对象在函数或代码块的执行期间存在,函数结束时自动销毁。局部变量是典型的自动存储期对象,它们在函数内部定义,函数结束时自动释放。
那么有没有人为命令的可以存储或者删除的对象呢?那就是动态创建对象,它允许你在程序运行时根据需要动态分配和释放内存。在处理不确定数量的对象、延迟初始化或者管理大型资源时非常有用。

2. 如何动态创建对象呢?

  1. 动态创建对象是通过new运算符来分配内存,而delete运算符用于释放内存。
#include <iostream>
using namespace std;int main() {// 动态创建一个整数int* x = new int;  // 分配一个整数的内存// 给动态分配的整数赋值*x = 42;// 输出动态分配的整数cout << "Value: " << *x << endl;// 释放内存delete x;  // 释放内存return 0;
}

在内存中的动态变化是这样的:
内存变化
2. 动态创建对象有以下初始化的方法:
初始化
3. 动态创建数组
如果需要动态创建一个数组,可以使用new[]和delete[]。

#include <iostream>
using namespace std;int main() {int size = 5;int* arr = new int[size];  // 动态分配一个整数数组// 给数组赋值for (int i = 0; i < size; i++) {arr[i] = i * 10;}// 输出数组内容for (int i = 0; i < size; i++) {cout << arr[i] << " ";}cout << endl;// 释放内存delete[] arr;  // 释放数组内存return 0;
}

3.动态对象的存储位置–堆

  • 堆(Heap)
    是一个动态分配的内存区域,主要用于存储程序运行时需要灵活管理的资源。堆的大小通常是动态的,可以根据需要分配和释放。
  • 堆的特点
    手动管理:堆上的内存分配和释放需要程序员手动管理(使用new和delete)。
    灵活大小:堆的大小可以动态扩展,适合存储大对象或动态数量的对象。
    生命周期可控:堆上的对象生命周期由程序员控制,可以跨越函数调用。
    访问速度较慢:堆的内存分配和释放速度比栈慢,因为需要额外的内存管理操作。

与之作为对比的栈存储区域,可以做一个简单的了解。

  • 栈(stack)

是一个后进先出(LIFO,Last In, First Out)的内存区域,主要用于存储函数调用的上下文信息和局部变量。栈的大小通常是固定的,由操作系统在程序启动时分配。

  • 栈的特点

自动管理:栈上的内存分配和释放是自动的,由编译器管理。
快速访问:栈的内存分配和释放速度非常快,因为它是连续的内存区域,且操作简单。
有限大小:栈的大小通常是有限的(例如几MB),不能动态扩展。
局部性:栈上的变量通常是函数内部的局部变量,生命周期与函数的调用相关。

4. 动态创建对象失败

如果由于内存空间不足,创建对象失败,通常会像下面这样处理:
抛出异常:默认情况下,C++中的new操作符会在内存分配失败时抛出std::bad_alloc异常。这使得程序在遇到内存分配失败时能够及时发现并处理错误。C++通过try、throw和catch三个关键字实现异常处理。try块用于包裹可能会抛出异常的代码。当try块中的代码抛出异常时,程序会跳转到相应的catch块处理异常。throw语句用于抛出一个异常。异常可以是任何类型,通常使用标准异常类或自定义异常类。catch块用于捕获和处理异常。可以有多个catch块来处理不同类型的异常。
例如:

// 循环动态创建数组对象(异常处理)#include <new>
#include <iostream>using namespace std;int main() {cout << "循环创建元素个数为30000的double型数组。\n";while (true) {try {double* a = new double[30000];  // 创建数组} catch (bad_alloc) {cout << "数组创建失败,程序中断。\n";return 1;}}
}

返回空指针:在某些情况下,程序员可能不希望因为内存分配失败而中断程序的执行。这时可以使用std::nothrow来防止抛出异常,而是返回一个空指针。如果在创建对象时指定“(nothrow)”,则也可以在不引起异常的情况下返回空指针,示例如下:

// 循环动态创建数组对象(抑制异常发生)#include <cstdlib>
#include <iostream>using namespace std;int main() {cout << "循环创建元素个数为30000的double型数组。\n";while (true) {double* a = new(nothrow) double[30000];  // 创建(抑制异常发生)if (a == NULL) {cout << "数组创建失败,程序中断。\n";return 1;}}
}

5. 使用void指针动态创建对象

void指针是一种特殊的指针,它可以指向任何数据类型。void指针的类型是void*。由于void指针不能直接访问它所指向的数据,因此需要进行类型转换。

#include <iostream>
using namespace std;int main() {int num = 42;void* ptr = &num;  // ptr指向num的地址// 通过类型转换访问数据cout << "Value: " << *static_cast<int*>(ptr) << endl;return 0;
}

在动态内存分配中,需要使用malloc和calloc等函数返回void*,再进行类型转换。malloc函数用于分配一块未初始化的内存。见下面例子。

#include <iostream>
#include <cstdlib>  // 用于malloc和free
using namespace std;int main() {// 动态分配一个整数int* ptrInt = static_cast<int*>(malloc(sizeof(int)));if (ptrInt != nullptr) {*ptrInt = 42;cout << "Integer value: " << *ptrInt << endl;free(ptrInt);  // 释放内存}// 动态分配一个字符数组char* ptrChar = static_cast<char*>(malloc(10 * sizeof(char)));if (ptrChar != nullptr) {strcpy(ptrChar, "Hello");cout << "String: " << ptrChar << endl;free(ptrChar);  // 释放内存}return 0;
}
#include <iostream>
#include <cstdlib>  // 用于calloc和free
using namespace std;int main() {// 动态分配一个整数数组int* ptrIntArray = static_cast<int*>(calloc(5, sizeof(int)));if (ptrIntArray != nullptr) {for (int i = 0; i < 5; i++) {ptrIntArray[i] = i * 10;}cout << "Integer array values: ";for (int i = 0; i < 5; i++) {cout << ptrIntArray[i] << " ";}cout << endl;free(ptrIntArray);  // 释放内存}// 动态分配一个字符数组char* ptrCharArray = static_cast<char*>(calloc(10, sizeof(char)));if (ptrCharArray != nullptr) {strcpy(ptrCharArray, "Hello");cout << "String: " << ptrCharArray << endl;free(ptrCharArray);  // 释放内存}return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2025 年浙江保安员职业资格考试高效备考指南​

浙江以创新活力著称&#xff0c;保安行业也在不断革新。2025 年考试报考条件常规&#xff0c;报名主要通过浙江省保安服务监管信息系统&#xff0c;方便快捷。​ 理论考试在传统知识基础上&#xff0c;加大对智能安防技术应用的考查&#xff0c;如人脸识别系统、智能监控报警系…

2022第十三届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组(题解解析)

记录刷题的过程、感悟、题解。 希望能帮到&#xff0c;那些与我一同前行的&#xff0c;来自远方的朋友&#x1f609; 大纲&#xff1a; 1、九进制转十进制-&#xff08;解析&#xff09;-简单的进制转化问题&#x1f604; 2、顺子日期-&#xff08;解析&#xff09;-考察日期 3…

Linux红帽:RHCSA认证知识讲解(十 二)调试 SELinux,如何管理 SELinux 的运行模式、安全策略、端口和上下文策略

Linux红帽&#xff1a;RHCSA认证知识讲解&#xff08;十 二&#xff09;调试 SELinux&#xff0c;如何管理 SELinux 的运行模式、安全策略、端口和上下文策略 前言一、SELinux 简介二、SELinux 的运行模式2.1 查看和切换 SELinux 模式 三、SELinux 预设安全策略的开关控制四、管…

Spring Cloud之服务入口Gateway之Route Predicate Factories

目录 Route Predicate Factories Predicate 实现Predicate接口 测试运行 Predicate的其它实现方法 匿名内部类 lambda表达式 Predicate的其它方法 源码详解 代码示例 Route Predicate Factories The After Route Predicate Factory The Before Route Predicate Fac…

下载安装Node.js及其他环境

提示&#xff1a;从Node版本降级到Vue项目运行 文章目录 下载Node.js环境配置配置环境变量 安装 cnpm&#xff08;我需要安装&#xff09;安装脚手架安装依赖安装淘宝镜像&#xff08;注意会更新&#xff09;cnpm vs npm 与新旧版本核心差异包管理器不同功能差异如何选择&#…

C++抽卡模拟器

近日在学校无聊&#xff0c;写了个抽卡模拟器供大家娱乐。 代码实现以下功能&#xff1a;抽卡界面&#xff0c;抽卡判定、动画播放、存档。 1.抽卡界面及判定 技术有限&#xff0c;不可能做的和原神一样精致。代码如下&#xff08;注&#xff1a;这不是完整代码&#xff0c;…

Redis 热key问题怎么解决?

Redis 热 Key 问题分析与解决方案 热 Key(Hot Key)是指被高频访问的某个或多个 Key,导致单个 Redis 节点负载过高,可能引发性能瓶颈甚至服务崩溃。以下是常见原因及解决方案: 1. 热 Key 的常见原因 突发流量:如明星八卦、秒杀商品、热门直播等场景。缓存设计不合理:如全…

第十四届蓝桥杯省赛真题解析(含C++详细源码)

第十四届蓝桥杯省赛 整数删除满分思路及代码solution1 &#xff08;40% 双指针暴力枚举&#xff09;solution 2&#xff08;优先队列模拟链表 AC&#xff09; 冶炼金属满分代码及思路 子串简写满分思路及代码solution 1&#xff08;60% 双指针&#xff09;solution 2&#xff0…

Matlab:三维绘图

目录 1.三维曲线绘图命令&#xff1a;plot3 实例——绘制空间直线 实例——绘制三角曲线 2.三维曲线绘图命令&#xff1a;explot3 3.三维网格命令&#xff1a;mesh 实例——绘制网格面 实例——绘制山峰曲面 实例——绘制函数曲线 1.三维曲线绘图命令&#xff1a;plot3 …

(51单片机)独立按键控制流水灯LED流向(独立按键教程)(LED使用教程)

源代码 如上图将7个文放在Keli5 中即可&#xff0c;然后烧录在单片机中就行了 烧录软件用的是STC-ISP&#xff0c;不知道怎么安装的可以去看江科大的视频&#xff1a; 【51单片机入门教程-2020版 程序全程纯手打 从零开始入门】https://www.bilibili.com/video/BV1Mb411e7re?…

React框架的Concurrent Mode

以下是关于 Concurrent Mode 的系统梳理: 一、Concurrent Mode 的诞生背景 传统渲染的局限性 同步阻塞:React 15 的 Stack Reconciler 无法中断渲染流程优先级缺失:用户交互与后台任务同等对待资源竞争:网络请求与渲染任务无法智能调度核心设计目标 可中断渲染:允许高优先…

Java 集合框架与 Stream 流深入剖析(重点详细讲解)

目录 引言 一、ArrayList 1. 概述 2. 特点 动态扩容 初始容量 扩容倍数 随机访问高效 插入和删除效率低 3. 代码示例 4. 分析 二、HashSet 1. 概述 2. 特点 唯一性 插入、删除和查找效率高 无序性 3. 代码示例 4. 分析 三、HashMap 1. 概述 2. 特点 键唯…