【问题标题】:Jagged array of classes锯齿状的类数组
【发布时间】:2012-06-18 22:28:04
【问题描述】:

在我的新工作中,我意识到迄今为止我实际使用的 C++ 技能有多么少。我现在正在通过一些自我强加的 OOP 练习而苦苦挣扎,并且被困在一系列参差不齐的类中。

代码如下:

#define CAT_ONE_COUNT    6
#define CAT_TWO_COUNT    7
#define CAT_THREE_COUNT 20
#define CAT_FOUR_COUNT   5
#define CAT_FIVE_COUNT   4
#define CAT_SIX_COUNT   20

enum {CAT_ONE, CAT_TWO, CAT_THREE, CAT_FOUR, CAT_FIVE};

class EntryList
{
    private:
        ScheduleEntry* catOne[CAT_ONE_COUNT];
        ScheduleEntry* catTwo[CAT_TWO_COUNT];
        ScheduleEntry* catThree[CAT_THREE_COUNT];
        ScheduleEntry* catFour[CAT_FOUR_COUNT];
        ScheduleEntry* catFive[CAT_FIVE_COUNT];
        ScheduleEntry* catSix[CAT_SIX_COUNT];

        ScheduleEntry** entries[];

    public:
        EntryList();
        ~EntryList();

        std::string getEntry(int cat, int entry);
};

EntryList::EntryList()
{
    catOne[0] = new ScheduleEntry("Pressups");
    catOne[1] = new ScheduleEntry("Situps");
    catOne[2] = new ScheduleEntry("Squats");
    catOne[3] = new ScheduleEntry("Bench Work");
    catOne[4] = new ScheduleEntry("Partner Versions");
    catOne[5] = new ScheduleEntry("Running + Numbers");

    entries[CAT_ONE] = &catOne;
}

显然,ScheduleEntry 是(并且成员函数是)在别处定义的,我在尝试编译时遇到的错误如下:

gfi@testbox:~/test$ g++ -o test -std=c++0x main.cpp
In file included from main.cpp:6:
EntryList.h: In constructor ‘EntryList::EntryList()’:
EntryList.h:40: error: cannot convert ‘ScheduleEntry* (*)[6]’ to ‘ScheduleEntry**’ in assignment

在阅读了我能找到的锯齿状数组之后,这是我认为实现它的最简单、最易读的方法。首先要做的事——是吗?有没有更简单的方法?

接下来(当然)编译器错误。我是怎么打错字的?

提前致谢。 =)

编辑:

找到快乐的媒介。

#define CAT_ONE_COUNT    6
#define CAT_TWO_COUNT    7
#define CAT_THREE_COUNT 20
#define CAT_FOUR_COUNT   5
#define CAT_FIVE_COUNT   4
#define CAT_SIX_COUNT   20

enum {CAT_ONE, CAT_TWO, CAT_THREE, CAT_FOUR, CAT_FIVE};

class EntryList
{
    private:
        ScheduleEntry** entries[6];

public:
    EntryList();
    ~EntryList();

    std::string getEntry(int cat, int entry);
};

EntryList::EntryList()
{
    entries[CAT_ONE] = new ScheduleEntry*[CAT_ONE_COUNT];
    entries[CAT_ONE][0] = new ScheduleEntry("Pushup");
    entries[CAT_ONE][1] = new ScheduleEntry("Situps");
    entries[CAT_ONE][2] = new ScheduleEntry("Squats");
    entries[CAT_ONE][3] = new ScheduleEntry("Bench Work");
    entries[CAT_ONE][4] = new ScheduleEntry("Partner Versions");
    entries[CAT_ONE][5] = new ScheduleEntry("Running + Numbers");
}

【问题讨论】:

  • std::vector 将使管理数组内容变得更加容易。
  • @CaptainObvlious:以牺牲数据的局部性和许多不必要的分配为代价。用作矩阵的向量向量可能很好,但如果代码对性能敏感,它可能会很慢,所以测试一下。
  • @EdS。 OP 更关心加强他们的 C++ 技能,因此代码性能并不是真正的问题。
  • @CaptainObvlious:同意,只是觉得我应该提一下。
  • ScheduleEntry** entries[]; 在 C++ 中是非法的,您始终必须指定数组大小。我认为由于 gcc C++ 扩展,代码可以工作。

标签: c++ jagged-arrays


【解决方案1】:

语法错误是:

entries[CAT_ONE] = &catOne; // Arrays are secretly pointers so this won't work

替换为:

entries[CAT_ONE] = catOne; // catOne is a ScheduleEntry* [], which is a ScheduleEntry**

你可能会逃脱这样的事情:

const int width = 6;
int height[width] = { 6, 7, 20, 5, 4, 20 };

ScheduleEntry*** entries = new (ScheduleEntry**)[width];
for (int i = 0; i < width; ++i) entries[i] = new (ScheduleEntry*)[height[i]];

entries[0][0] = new ScheduleEntry("Pressups");
entries[0][1] = new ScheduleEntry("Situps");
entries[0][2] = new ScheduleEntry("Squats");
entries[0][3] = new ScheduleEntry("Bench Work");
entries[0][4] = new ScheduleEntry("Partner Versions");
entries[0][5] = new ScheduleEntry("Running + Numbers");
// etc etc

【讨论】:

  • 成功了!谢谢你。但是,我无法理解三重间接背后的目的。我所需要的只是一个指向动态分配数组的指针数组,对吧?
  • 嗯,您将对象存储为指针,因此要保持一个零维数组(一个对象),您需要一个 ScheduleEntry*。数组是连续的内存块,并被存储和视为指向数组基地址的指针(其内存块的开头)。所以第一个数组是一个指向 ScheduleEntry* 数组的指针。因此,最外面的数组是指向一堆指针的指针,每个指针都指向一堆ScheduleEntry*(一个ScheduleEntry***)。通常,要添加另一个维度,您需要更深入地增加一个指针。这能回答你的问题吗?
  • 此外,这就是为什么动态数组分配通常类似于以下形式:Something * array = new Something[size];
  • 好吧,我明白了(我想,哈哈)。但是,删除 & 符号然后尝试通读列表会产生 seg 错误。 =) 似乎你的三重间接是必要的,虽然 GCC 不喜欢你在那里的沉思。
  • 知道了。看上面。再次感谢。 =)
猜你喜欢
  • 2015-09-23
  • 2012-06-04
  • 2020-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-21
  • 2015-07-01
相关资源
最近更新 更多