创建基于堆的2D数组而不使用双指针语法?

如何解决创建基于堆的2D数组而不使用双指针语法?

我需要声明一个2D数组作为类的成员变量。我不能使用STL(因此,没有向量),并且被要求避免使用双/三重指针。我希望能够使用下标符号来引用此2D数组中的元素,例如arr[0][0]。由于数组的大小,还必须在堆上声明该数组。

由于我的要求,StackOverflow上的现有答案都无法满足我的需求。

我一直想做的是:

class MyClass {
 public:
  MyClass() : arr(new int[1000][2]) {}

  // other stuff here

 private:
  int arr[1000][2];
};

编译该类后,我得到的错误是“无法初始化类型为int *的左值的类型int[1000][2]的参数”。显然,我可以使用指针语法解决此问题,但是如上所述,为了代码清晰起见,我被要求使用“数组语法”。 我希望对C ++有更好理解的人可以解释如何使用“数组语法”。

解决方法

当然,您可以在没有双/三指针的情况下执行此操作。您甚至可以在类声明中不使用任何指针的情况下执行此操作。但是首先让我们看一下更常见的方法。 2D数组是1D数组的简单扩展。

以标准方式开始,使用vector对1000个int的1D数组进行此操作。指针arr在堆栈上,但指向堆上1000个整数的数组。

class MyClass {
public:
    MyClass() : arr(new int[1000]) {}

private:
    int *arr;
};

以常规方式访问元素。例如arr[0]=42;

将其扩展到堆中的2D数组是上述内容的简单扩展。 您需要将成员变量声明为指向1D数组的指针,而不是基本类型。

class MyClass {
public:
    MyClass() : arr(new int[1000][2]) {}

private:
    int (*arr)[2];
};

类似地,您可以按照通常的方式引用2D数组的元素:arr[0][0]=42;

最后,除了new所需的指针之外,还有一种方法可以完全消除指针。在这里,我们初始化一个参考。诀窍是在新的[1]中添加第三级,以便*new返回一个实际的2D int数组对象。从结构上讲,它与上面的指针版本没有什么不同,但是让我们直接初始化对2D int数组的引用。当然这不是一个常见的习惯用法,所以我会坚持使用ptr方法。

class MyClass {
public:
    MyClass() : arr(*new int[1][1000][2]) {}
    ~MyClass() {delete[] arr;}
//private:  // to test
    int(&arr)[1000][2];
};


int main()
{
    MyClass obj;
    obj.arr[2][1] = 42;
}
,

当您的类中有一个数组,并且您使用new创建该类的新实例时,该数组就在堆上。您仍然可以使用arr[i][j]访问该数组。

为什么不做这样的事情?

class myClass {
  public:
    int arr[1000][2];
};

int main() {
    myClass* test = new myClass;
    for (int i = 0; i < 1000; i++) {
        for (int j = 0; j < 2; j++) {
            test->arr[i][j] = 5;
         }
     }
 }
,

您可以使用2个类来实现这一目标。

class BaseArray {
public:
    int& operator[](int x) { return this->arr[x]; }
    int operator[](int index) const { return this->arr[index]; }

    int arr[2];
};

class myClass {
public:
    myClass() {}
    ~myClass() {}

    BaseArray& operator[](int index) { return this->arr[index]; }
    BaseArray operator[](int index) const { return this->arr[index]; }

    BaseArray arr[1000];
};

(可选)使用可以使用的模板来使此类更加动态。

template<class TYPE,int arraySize>
class BaseArray {
public:
    TYPE& operator[](int x) { return this->arr[x]; }
    TYPE operator[](int index) const { return this->arr[index]; }

    TYPE arr[arraySize];
};

template<class TYPE,int dim1,int dim2>
class myClass {
public:
    myClass() {}
    ~myClass() {}

    BaseArray<TYPE,dim2>& operator[](int index) { return this->arr[index]; }
    BaseArray<TYPE,dim2> operator[](int index) const { return this->arr[index]; }

    BaseArray<TYPE,dim2> arr[dim1];
};

int main()
{
    myClass<int,1000,2> myArray;
}

编辑
提供数组尺寸int arr[1000][2];时,变量将自动分配到堆栈中。如果数组需要完全动态,则可以使用双指针int** arr = { nullptr };并在构造函数中对其进行初始化,如下所示。

class myClass {
public:
    myClass()
    {
        arr = new int* [1000];
        for (int i = 0; i < 1000; ++i)
            arr[i] = new int[2];
    }

    ~myClass()
    {
        /* Make sure to delete or else it might flag a memory error. */
        for (int i = 0; i < 1000; ++i)
            delete[] arr[i];

        delete[] arr;
    }

    int** arr = { nullptr };
};

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-