【问题标题】:Declare array of fixed length in nested classes在嵌套类中声明固定长度的数组
【发布时间】:2014-06-23 03:50:00
【问题描述】:

我有一个 A 类,它有一个嵌套的 B 类。A 类将创建 B 类的 n(运行时参数)实例。

在 A 的构造函数中,在需要在运行时进行计算之后,我计算一个大小,比如说 s。

现在,每个 B 类都将保存一个大小为 s 的数组。

但是,我不允许使用 .cpp 文件,所有工作都必须在头文件中完成。

据我了解,这意味着我不能使用这些方法(使用static):

class B {

static const int s;
int a[s];

};

所以,我决定使用enum,但我无法让它工作(即使使用 C++11 的enum class)。 这个想法是你做这样的事情:

class B {

enum { s = 50 };
int a[s];

};

但我不知道运行前的s

当然,我可以使用std::vectordynamic allocation

但是因为:

1)我只需要旧好的数组的功能(丢弃向量)

2)我在构造B的实例之前,知道数组的大小(丢弃动态分配)

关于std::dynarray下面讨论:

不幸的是,不在C++14,而是在array TSC++17Source,感谢 manlio。

然而,丢弃是一个沉重的词。我的意思是,我听说自动分配更快,但动态分配可以让您分配更多空间。此外,在发布模式下,与数组相比,向量并没有那么糟糕。

【问题讨论】:

  • 如果你知道编译时的大小,为什么不使用std::array
  • @40two OP 明确声明它在运行前不知道 s
  • @40two 大小在编译时是已知的。
  • OP 似乎想要为会员提供一些 VLA。
  • 这有点过早优化的味道。根据 Knuth 的说法,它是邪恶的。使用std::vector,测量发布版本的性能。

标签: c++ arrays c++11 enums nested-class


【解决方案1】:

即使元素类型相同但大小不同的两个数组也是不同的类型。例如char[10]char[11] 是不同的类型。同样,如果两个类的成员的类型在这两个类之间不同,那么这些类定义不同的类型并具有不同的大小(我的意思是运算符 sizeof)。你也不能实例化一个不完整类型的对象。

如果您的编译器支持std::dynarray 类,我建议您使用它。否则你可以使用std::vector

【讨论】:

  • 每个类 B 都将具有相同的确切大小,但编译器不知道这一点。 std::dynarray 肯定是要走的路,但我不支持 C++14。
  • @G。 Samaras 在这种情况下,除了手动分配动态数组之外,我没有看到其他方法。
  • 那么,动态分配(家务是微不足道的)将是您的选择,而不是向量?题外话:既然这个问题被否决了,我觉得我应该关闭它,但因为有答案,我不能。我该怎么办?但是,当 C++14 更接近时,您的答案似乎很适合将来参考。
  • @G。萨马拉斯 这不是我的选择。这是您的选择,因为您说过您可能不使用标准容器。至于我,我对你的帖子投了赞成票。
  • 旧数组不是标准的吗?我想我会选择std::vectorreserveshrink_to_fit。谢谢。
【解决方案2】:

您不能在 C++ 中声明可变大小的数组。编译器必须提前知道数组的大小。请改用std::vector,然后使用std::vector::shrink_to_fit 减少其容量以适应其大小。:

class B {
  ...
  std::vector<int> a;
  ...
};

【讨论】:

  • +1 表示shrink_to_fit 的想法。将来,请仔细阅读 OP的问题,以免您做不必要的 cmets 并不得不多次编辑您的答案。如果你认为我错了,就放手吧。 :)
  • 查看马萨在弗拉德关于shrink_to_fit 的回答中的评论。
  • 你问的很好!你得到了我的 +1!
  • @G.Samaras 基本上没有更好的方法了。
【解决方案3】:

有两个问题。首先,请注意类的嵌套仅适用于范围。嵌套类不会在外部类中自动创建该类的数据成员。所以通常你会在外部类中定义嵌套类类型的成员,如下所示。其次,您不能根据在 C++ 中运行时计算的大小来定义数组。

也就是说,您可以轻松使用std::vector。如果出于某种原因必须在头文件中完成所有操作,您可以在类中定义它们,但如果它们超过几行,那将是一个坏主意。

#include <vector>
#include <cstddef>

class A {
    private:
        class B {
            friend A;
            B(size_t n) : array(n) {}
            std::vector<int> array;
        };
    public:
        // Initialize b_member based on some computation.
        A(int i) : b_member(i + 2), b_ptr_member(new B(i + 3)) {}
        ~A() { delete b_ptr_member; }
    private:
        B b_member;
        B *b_ptr_member;
};

int main() {
    A a(10);
}

【讨论】:

  • A 的数据成员可能是指向 B 类的指针。B 的构造函数将被 A 的构造函数调用 n 次。这不能保证其中的顺序构造函数会被调用吗?
  • @G.Samaras:是的,如果你这样编码的话。我将编辑答案以使其更清楚。
  • +1 用于分析答案,并且是第一个以良好方式回答问题的人。但是,我选择 Vlad 的答案,因为它可以被未来的用户使用。 :)
【解决方案4】:

答案是:使用std::vector。这个项目:

1)我只需要旧好的数组的功能(丢弃 向量)

并不真正适用。您确实需要旧的好数组不具备的额外功能(即,分配一个您在运行时只有大小的数组)。

如果你有一个最近的编译器/标准库,也许你可以访问&lt;experimental/dynarray&gt;...,恕我直言,这只是&lt;vector&gt; 的残缺版本,但对于每个人来说,它都有自己的:D

【讨论】:

  • 我想到了我需要的功能,一旦结构被创建。 +1 说明需求!
猜你喜欢
  • 2017-04-29
  • 2012-05-28
  • 1970-01-01
  • 1970-01-01
  • 2019-03-27
  • 2019-05-07
  • 1970-01-01
  • 2012-12-17
  • 1970-01-01
相关资源
最近更新 更多