【问题标题】:Function that returns a pointer to const 2-d array (C++)返回指向 const 二维数组 (C++) 的指针的函数
【发布时间】:2010-06-24 18:39:51
【问题描述】:

我是一名间歇性程序员,最近似乎忘记了很多基础知识。

我创建了一个类SimPars 来保存几个二维数组;下面显示的是demPMFs。我要将指向SimPars 实例的指针传递给其他类,并且我希望这些类能够使用SimPars 访问器函数读取数组。速度和内存很重要。

我知道使用向量通常会更简单,但在这种情况下,我真的很想坚持使用数组。

如何为数组编写访问器函数?如果我对第 n 个数组索引感兴趣,如何使用返回的指针访问它? (我应该为数组的特定索引编写一个单独的访问器函数吗?)下面的内容肯定是错误的。

// SimPars.h
#ifndef SIMPARS_H
#define SIMPARS_H
#include "Parameters.h" // includes array size information

class SimPars {
 public:
  SimPars( void );
  ~SimPars( void );

  const double [][ INIT_NUM_AGE_CATS ] get_demPMFs() const;

 private:
   double demPMFs[ NUM_SOCIODEM_FILES ][ INIT_NUM_AGE_CATS ];

};
#endif


// SimPars.cpp
SimPars::SimPars() {
 demPMFs[ NUM_SOCIODEM_FILES ][ INIT_NUM_AGE_CATS ];
 // ...code snipped--demPMFs gets initialized...
}

//...destructor snipped
const double [][ INIT_NUM_AGE_CATS ] SimPars::get_demPMFs( void ) const {
  return demPMFs; 
}

我将非常感谢您对建议的解决方案进行某种解释。

【问题讨论】:

  • 我很确定double demPMFs[][ INIT_NUM_AGE_CATS ]; 的成员声明是非法的。这真的可以编译吗?
  • 感谢您的关注。修正了错字。我在原始代码中有大小。
  • 您能否详细说明您实际想要实现的目标?将二维数组视为指向指针的数组:demPMFs**,那么您不需要在返回类型中指定任何大小,如const double [][ INIT_NUM_AGE_CATS ] get_demPMFs() const; ...
  • 我希望其他接收指向 SimPars 实例的指针的类能够读取 demPMF。我认为这可以通过让 SimPars get 函数返回一个指向数组的指针来实现。

标签: c++ arrays pointers


【解决方案1】:

基本上,您有三种选择:通过引用返回整个数组,通过指针返回第一行,或者通过指针返回整个数组。这是实现:

typedef double array_row[INIT_NUM_AGE_CATS];

typedef array_row array_t[NUM_SOCIODEM_FILES];

array_t demPMFs;

const array_t& return_array_by_reference() const
{
    return demPMFs;
}

const array_row* return_first_row_by_pointer() const
{
    return demPMFs;
}

const array_t* return_array_by_pointer() const
{
    return &demPMFs;
}

以下是用例:

SimPars foo;

double a = foo.return_array_by_reference()[0][0];
double b = foo.return_first_row_by_pointer()[0][0];
double c = (*foo.return_array_by_pointer())[0][0];

如何只返回数组的第 n 行?

同样,您有三个选择:

const array_row& return_nth_row_by_reference(size_t row) const
{
    return demPMFs[row];
}

const double* return_first_element_of_nth_row_by_pointer(size_t row) const
{
    return demPMFs[row];
}

const array_row* return_nth_row_by_pointer(size_t row) const
{
    return demPMFs + row;
}

【讨论】:

  • 谢谢。如何只返回数组的第 n 行?
  • @Sarah:我更新了我的帖子。在这两种情况下,我更喜欢第一个解决方案,通过引用返回您感兴趣的完整内容。
【解决方案2】:
const double (* get_demPMFs() const)[INIT_NUM_AGE_CATS];

或者,使用typedef(但这似乎不太干净......)。

class SimPars {
    typedef const double (*ConstDemPMFType)[INIT_NUM_AGE_CATS];

    double demPMFs[NUM_SOCIODEM_FILES][INIT_NUM_AGE_CATS];
public:
    ConstDemPMFType get_demPMFs() const;
};

请注意,您不能返回数组(g++ 拒绝编译)。但是数组的数组可以衰减为指向数组的指针,所以返回的是后者。

【讨论】:

  • (* get_demPMFs() const) -> 啊,这就是括号和 const 必须去的地方,我与 C 声明符语法斗争了 5 分钟,然后放弃了,退回到古老的 typedef :)
  • @Fred 这是identity 擅长的地方。 identity<const double[INIT_NUM_AGE_CATS]>::type *get_demPMFs() const;
【解决方案3】:

从逻辑上讲,这个问题与数据成员有关。是否允许用户修改它。如果您想授予另一个类对该成员的完全访问权限,则不一定需要 getter/setter,特别是如果您是唯一的用户。您可以将成员设为公开。

如果您的班级最好控制用户访问成员的方式,那么您可以只使用 getter 来强制执行只读访问。如果您不想对二维数组感到困惑,那么最简单的方法是使用一个内联函数来获取用户类的元素:

const double& getElem( int x, int y ) const { return demPMF[x][y] }

在这里做边界检查是有意义的,但考虑到你坚持使用数组,如果你的分析器证明你负担不起,这个函数只会允许访问你的数组。

如果您想进一步阐述,发表评论...

【讨论】:

  • 如何通过 const 引用传递整个数组更不安全?
  • O,这绝对不是不安全,但更令人困惑,至少对我来说这要简单得多。我仍在尝试找出你和肯尼答案的语法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-21
  • 2017-06-11
  • 2021-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多