【问题标题】:Constructor initilizer list for a class with multiple arrays (C++11 is ok, boost and std::vector are not)具有多个数组的类的构造函数初始化列表(C++11 可以,boost 和 std::vector 不行)
【发布时间】:2012-11-15 18:44:54
【问题描述】:

我还不了解用于在构造函数初始化程序列表中初始化数组的新 C++11 语法。我不再坚持使用 C++03,但由于程序限制,我不能使用 boost 或 std::vector。

FOO 的实例必须通过构造函数调用来确定大小,并且表现得好像 x 和 y 的大小是静态已知的。新的 C++11 特性是否允许这样做?

我不确定std::initializer_list<> 是否或如何提供帮助。

class FOO
{
public:
    // this constructor needs to size x = count and y = count * 4
    FOO(int count) : 
    {
        // interate over x and y to give them their initial and permenent values
    }
private:
    const BAR x[];
    const TAR y[];
};

#include "foo.h"
void main(void)
{
    // both need to work as expected
    FOO alpha(30);
    FOO * bravo = new FOO(44);
}

【问题讨论】:

  • “必须通过构造函数调用来确定大小,并且表现得好像 x 和 y 的大小是静态已知的”——您确实意识到这些是相互矛盾的要求,对吧?另外,请告诉我不允许您使用std::vector 的“程序约束”。
  • 我同意矛盾的要求。我有大量静态只读数据需要可供此类的实例使用。我不希望堆或堆栈上的数据。从那以后,我一直在看 Marcus 的问题link,更重要的是 Bill Forster 的回复。我的数据可能太大而无法直接放入源代码。 > [1,000,000]。我希望有某种方法可以直接将这些记录直接加载到给定内存位置的 ram/rom 中,我可以从指针中使用它。
  • @wapadomo:欢迎来到XY Problem。您询问了 initializer_lists 和初始化,但您真正想要的是一种将批量数据存储在可执行文件中并获得指向它的指针的方法。那么你应该问过那个

标签: c++ constructor c++11 initializer-list


【解决方案1】:

你不能做你想做的事。数组的大小必须是编译时常量。虽然在您的特定用例中提供给构造函数的值可能是编译时常量,但 C++ 无法知道这一点。

此外,作为一种静态类型语言,C++ 需要能够在编译时计算类的大小。 sizeof(Foo) 需要有一个精确的单一值。而你的不能。

初始化列表对你没有帮助。您需要两个运行时大小的数组;这就是std::vector 的用途。如果你想要编译时大小的数组,你需要使用模板类型:

template<int count>
class FOO
{
public:
    FOO(initializer_list<Whatever> ilist)
    {
        // interate over x and y to give them their initial and permenent values
    }

private:
    const BAR x[count];
    const TAR y[count * 4];
};

#include "foo.h"
void main(void)
{
    // both need to work as expected
    FOO<30> alpha;
    FOO<44> * bravo = new FOO<44>;
}

【讨论】:

  • 模板是获得编译时大小数组的唯一方法吗?如果我想在编译时使用大量数据(数百万 BAR 和 TAR)初始化数组怎么办?源代码肯定不会那么大。
  • @wapadomo:为什么不呢?一旦实例化,模板最终与class Foo { private: const BAR x[50000000]; ... }; 没有什么不同。这是一个完全有效的struct。您是否可以通过initializer_list 初始化初始化此类数组的所有元素取决于您的编译器。那么您的编译器可以处理具有数百万行的源文件吗?该问题的答案与模板无关。
  • @wapadomo:就个人而言,我想说的是,无论您是否使用模板,您的可执行文件中都不应该有 数百万 个静态条目。为什么不加载文件?
【解决方案2】:

除了 Nicol Bolas 使用模板参数使大小在编译时可配置的答案之外,您还可以在堆上分配内存:

class FOO
{
public:
    // this constructor needs to size x = count and y = count * 4
    FOO(int count) : x(new BAR[count]), y(new TAR[count])
    {
        // interate over x and y to give them their initial and permenent values
    }

    // Need a destructor to free the memory we allocated in the constructor
    ~FOO()
    {
        delete [] y;
        delete [] x;
    }
private:
    const BAR* x;
    const TAR* y;
};

【讨论】:

  • 现在你进入了三法则的整个交易......你甚至没有在答案中提到它。
  • 不仅如此,如果new TAR[count] 抛出,此代码当前会泄漏内存。基本上,如果你想走这条路,你最好的办法是重新实现std::vector或类似的东西。
猜你喜欢
  • 2015-08-05
  • 1970-01-01
  • 2020-05-05
  • 2014-05-20
  • 2016-07-19
  • 2016-05-03
  • 2020-10-28
  • 2020-09-03
  • 2011-08-22
相关资源
最近更新 更多