[C++面向对象]很难蒙混过关的CArray3d三维数组模板类

07:很难蒙混过关的CArray3d三维数组模板类

描述

实现一个三维数组模版CArray3D,可以用来生成元素为任意类型变量的三维数组,输出指定结果

#include <iostream>
#include <iomanip> 
#include <cstring>
using namespace std;
template <class T>
class CArray3D
{//此处填充代码
};CArray3D<int> a(3,4,5);
CArray3D<double> b(3,2,2);
void PrintA()
{for(int i = 0;i < 3; ++i) {cout << "layer " << i << ":" << endl;for(int j = 0; j < 4; ++j) {for(int k = 0; k < 5; ++k) cout << a[i][j][k] << "," ;cout << endl;}}
}
void PrintB()
{for(int i = 0;i < 3; ++i) {cout << "layer " << i << ":" << endl;for(int j = 0; j < 2; ++j) {for(int k = 0; k < 2; ++k) cout << b[i][j][k] << "," ;cout << endl;}}
}int main()
{int No = 0;for( int i = 0; i < 3; ++ i ) {a[i];for( int j = 0; j < 4; ++j ) {a[j][i];for( int k = 0; k < 5; ++k )a[i][j][k] = No ++;a[j][i][i];	}}PrintA();memset(a[1],-1 ,20*sizeof(int));	memset(a[1],-1 ,20*sizeof(int));PrintA(); memset(a[1][1],0 ,5*sizeof(int));	PrintA();for( int i = 0; i < 3; ++ i )for( int j = 0; j < 2; ++j )for( int k = 0; k < 2; ++k )b[i][j][k] = 10.0/(i+j+k+1);PrintB();int n = a[0][1][2];double f = b[0][1][1];cout << "****" << endl;cout << n << "," << f << endl;return 0;
}

输入

输出

等同于样例

样例输入

样例输出

layer 0:
0,1,2,3,4,
5,6,7,8,9,
10,11,12,13,14,
15,16,17,18,19,
layer 1:
20,21,22,23,24,
25,26,27,28,29,
30,31,32,33,34,
35,36,37,38,39,
layer 2:
40,41,42,43,44,
45,46,47,48,49,
50,51,52,53,54,
55,56,57,58,59,
layer 0:
0,1,2,3,4,
5,6,7,8,9,
10,11,12,13,14,
15,16,17,18,19,
layer 1:
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
layer 2:
40,41,42,43,44,
45,46,47,48,49,
50,51,52,53,54,
55,56,57,58,59,
layer 0:
0,1,2,3,4,
5,6,7,8,9,
10,11,12,13,14,
15,16,17,18,19,
layer 1:
-1,-1,-1,-1,-1,
0,0,0,0,0,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
layer 2:
40,41,42,43,44,
45,46,47,48,49,
50,51,52,53,54,
55,56,57,58,59,
layer 0:
10,5,
5,3.33333,
layer 1:
5,3.33333,
3.33333,2.5,
layer 2:
3.33333,2.5,
2.5,2,
****
7,3.33333

提示

建议做法:
1. a[i][j][k] 这个表达式的第一个[]返回一个内部类的对象,该内部类也重载了[],且返回值为指针。
2. 必要时需重载对象到指针的强制类型转换运算符

解题分析

要想实现一个三维数组类,如果只是要求存储一些数据,并且通过a[i][j][k]运算符去取出数据,那么我们直接用循环和new操作符即可,但是注意这样得到的三维数组是个假三维数组,它的内存并不是连续存储的,而是分多块存储,这并不符合本题的要求,也不能直接用memset去操作超出分配的内存的一整片连续空间。

template <class T>
class CArray3D
{// 在此处补充你的代码T*** Array;int x,y,z;
public:CArray3D(int a,int b,int c) : x{a},y{b},z{c}{Array = new T**[a];for(int i=0;i<b;i++){Array[i] = new T*[b];for(int j=0;j<c;j++){Array[i][j] = new T[c];}}}T** operator[](int i){return Array[i];}};

所以正确的做法是啥子类?首先,C/C++里面真正的数组内存都是连续的,那我们创建一个T *Array; 然后初始化时分配一整片三维数组需要的连续的内存,这个肯定没问题。那我们怎么做到a[i][j][k]三个运算符的重载呢? 分析一下,最后一个[k]运算后我们希望是T 那么第二个[j]运算后我们希望是T*,也就是说第一个[i]运算后我们希望得到T**?这显然不是一件容易的事情。

换个思路,我们不妨这样去想,如果是一个二维数组,我们要分配一个连续的内存空间并且满足上述[]运算符要求,是不是很简单?

template<class T>
class CArray2D {friend class CArray3D<T>;private:T* data;int Y, Z;public:CArray2D() : data(nullptr), Y(0), Z(0) {}void allocate(int y, int z) {Y = y; Z = z;data = new T[Y * Z]();}T* operator[](int y) {return data + y * Z;}const T* operator[](int y) const {return data + y * Z;}operator T*(){return data;}~CArray2D() {delete[] data;}};

注意,这里的强制类型转换函数是为了迎合memset!

所以最后代码就是这样的~

template <class T>
class CArray3D {
public:class CArray2D {friend class CArray3D<T>;private:T* data;int Y, Z;public:CArray2D() : data(nullptr), Y(0), Z(0) {}void allocate(int y, int z) {Y = y; Z = z;data = new T[Y * Z]();}T* operator[](int y) {return data + y * Z;}const T* operator[](int y) const {return data + y * Z;}operator T*(){return data;}~CArray2D() {delete[] data;}};private:CArray2D* array2D;int X;public:CArray3D(int x, int y, int z) : X(x) {array2D = new CArray2D[X];for (int i = 0; i < X; ++i) {array2D[i].allocate(y, z);}}CArray2D& operator[](int x) {return array2D[x];}const CArray2D& operator[](int x) const {return array2D[x];}~CArray3D() {delete[] array2D;}
};

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

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

相关文章

微信小程序如何进行npm导入组件

文章目录 目录 文章目录 前言 一、安装node 二、微信小程序通过npm安装组件&#xff08;以Vant-weapp为例&#xff09; 一、Vant-weapp下载 二 、修改 app.json 三 、修改 project.config.json 四 、 构建 npm 包 前言 微信小程序使用npm导入有很多的教程&#xff0c;我…

vue基础教程(5)——十分钟吃透vue路由router

同学们可以私信我加入学习群&#xff01; 正文开始 前言一、路由概念二、路由使用三、创建路由对应的组件四、给整个项目一个入口总结 前言 前面的文章运行成功后&#xff0c;页面显示如下&#xff1a; 在这个页面中&#xff0c;点击Home和About都会切换右面的页面内容&#…

一百以内累加(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS #include <stdio.h>int main() {//初始化变量值&#xff1b;int a 2;int result 1;//循环运算&#xff1b;while (a < 100){//加&#xff1b;result a result;//改变变量值&a…

Spring(详细介绍)

目录 一、简介 1、什么是Spring&#xff1f; 2、Spring框架的核心特性 3、优点 二、IOC容器 介绍 1、获取资源的传统方式 2、控制反转方式获取资源 3、DI 4、IOC容器在Spring中的实现 入门案例 1、创建Maven Module 2、引入依赖 3、创建HelloWorld类 4、在Spring的配…

【动手学深度学习】深入浅出深度学习之利用神经网络识别螺旋状数据集

目录 &#x1f31e;一、实验目的 &#x1f31e;二、实验准备 &#x1f31e;三、实验内容 &#x1f33c;1. 生成螺旋状数据集 &#x1f33c;2. 打印数据集 &#x1f33c;3. 编程实现 &#x1f33b;仿射层-Affine类 &#x1f33b;传播层-Sigmoid类 &#x1f33b;损失函数…

Unity urp渲染管线下,动态修改材质球surfaceType

在项目中遇到了需要代码动态修改材质球的surfaceType&#xff0c;使其动态切换是否透明的需求。 urp渲染管线下&#xff0c;动态修改材质球的surfaceType&#xff0c;查了大部分帖子&#xff0c;都有一些瑕疵&#xff0c;可能会造成透明后阴影投射有问题。 其次在webgl平台上…

简单了解波 Mono-repo Multi-repo(Poly-repo)

Mono-repo 和 Multi-repo 是软件开发中代码管理的两个不同策略。Mono-repo & Multi-repo 孰优孰劣是个老生常谈得话题了&#xff0c;这里就不 PK 了&#xff0c;“略微”看下两者区别。 当我们使用 Git 作为版本控制系统管理项目的代码时&#xff0c;那么 monorepo 与 mul…

iptables 与 firewalld 防火墙

iptables iptables 是一款基于命令行的防火墙策略管理工具 四种防火墙策略&#xff1a; ACCEPT&#xff08;允许流量通过&#xff09; 流量发送方会看到响应超时的提醒&#xff0c;但是流量发送方无法判断流量是被拒绝&#xff0c;还是接收方主机当前不在线 REJECT&#xff08…

上位机图像处理和嵌入式模块部署(qmacvisual寻找圆和寻找直线)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面有几篇文章&#xff0c;我们谈到过直线拟合、圆拟合和椭圆拟合。当时&#xff0c;我们的做法是&#xff0c;先找到了轮廓&#xff0c;接着找到…

设计模式-概述篇

1. 掌握设计模式的层次 第1层&#xff1a;刚开始学编程不久&#xff0c;听说过什么是设计模式第2层&#xff1a;有很长时间的编程经验&#xff0c;自己写了很多代码&#xff0c;其中用到了设计模式&#xff0c;但是自己却不知道第3层&#xff1a;学习过了设计模式&#xff0c;…

Stable Diffusion本地部署全攻略:从概念到实战

目录 一、概念篇&#xff1a;什么是Stable Diffusion&#xff1f; 二、原理篇&#xff1a;Stable Diffusion是如何工作的&#xff1f; 三、作用篇&#xff1a;Stable Diffusion能为我们带来什么&#xff1f; 四、教程篇&#xff1a;如何在本地部署Stable Diffusion&#xf…

UDP send 出现大量“Resource temporarily unavailable”

背景 最近排查用户现场环境&#xff0c;查看日志出现大量的“send: Resource temporarily unavailable”错误&#xff0c;UDP设置NO_BLOCK模式&#xff0c;send又发生在进程上下文&#xff0c;并且还设置了SO_SNDBUF 为8M&#xff0c;在此情况下为什么还会出现发送队列满的情况…

Composer常见错误及解决方案

Composer常见错误及解决方案 Composer是PHP的依赖管理工具&#xff0c;它使得在PHP项目中管理和安装依赖库变得简单。然而&#xff0c;在使用Composer时&#xff0c;开发者可能会遇到一些常见的错误。在本文中&#xff0c;我们将探讨一些常见的Composer错误以及相应的解决方案…

【JavaWeb】Day28.SpringBootWeb请求响应——请求(一)

前言&#xff1a; 我们在开发web程序时呢&#xff0c;定义了一个控制器类Controller&#xff0c;请求会被部署在Tomcat中的Controller接收&#xff0c;然后Controller再给浏览器一个响应。 而在请求响应的过程中是遵循HTTP协议的。 但是&#xff0c;在Tomcat这类Web服务器中&a…

Jupyter Notebook启动及其常用快捷键

添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 1.JupyterNotebook 第一种启动方式 点击 windows 电脑左下角开始 > 搜索 Anaconda > 点击 Anaconda Prompt 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 在命令行窗口输入&…

Java 多附件zip下载完整代码

需求:Java根据Url把多个文件下载到指定的文件夹目录&#xff0c;然后再将文件夹目录打包成zip导出. Slf4j Controller("test") Api(value "zip文件上传API", tags {"zip文件上传"}) public class Download { Autowired private Recor…

打造高效安全的电池管理 | 基于ACM32 MCU的两轮车充电桩方案

前 言 随着城市化进程的加快、人们生活水平的提高和节能环保理念的普及&#xff0c;越来越多的人选择了电动车作为代步工具&#xff0c;而两轮电动车的出行半径较短&#xff0c;需要频繁充电&#xff0c;因此在城市中设置两轮车充电桩就非常有必要了。城市中的充电桩不仅能解决…

NoSQL注入基础及思路

君衍. 一、NoSQL1、为什么使用NoSQL2、RDBMS与NoSQL区别3、NoSQL产品4、NoSQL 数据库分类 二、MongoDB1、认识MongoDB2、MongoDB特性3、MongoDB工作方式4、MongoDB缺陷5、MongoDB基本概念6、数据库Database7、文档Document8、集合Collection 三、MongoDB基本操作1、数据库操作2…

C++类继承基础3——访问控制与继承

私有继承 在C中&#xff0c;私有继承是一种继承方式&#xff0c;它定义了一个私有派生类&#xff0c;也称为派生类。私有继承意味着派生类继承了基类的所有成员&#xff0c;但这些成员在派生类中是私有的&#xff0c;对外部不可见。 要进行私有继承请使用private关键字&#…

蓝桥杯十四届JavaB组省赛ABCD

A阶乘求和 从1&#xff01;一直加到202320232023&#xff01;&#xff0c;如果一个个算阶乘的后九位再相加&#xff0c;算法可以实现&#xff0c;但是运算量很大&#xff0c;需要一段时间。用计算器算了一下100&#xff01;阶乘发现后几位都是0&#xff0c;因此加到20232023202…