在构造函数中初始化数组,而不使用默认构造函数或赋值

spr*_*aff 4 c++ arrays constructor default initialization

考虑:

struct A {

 A (int);

 A (const A &);
};

struct B {

 A foo [2];

 B (const A & x, const A & y)
 : foo {x, y} /* HERE IS THE PROBLEM */
 {}
};
Run Code Online (Sandbox Code Playgroud)

我期待这个工作,因为我在GCC4.3中使用C++ 0x支持,据称支持初始化列表.没有快乐.

我有一个没有默认构造函数的类A. 这是不容谈判的.分配后默认不是一个选项.

我正在尝试创建使用A的B.B :: foo可能不是std :: vector.

我怎么能初始化B::fooB(...),构建它的元素恰好一次?

目前,我正在考虑用B替换B.

struct B {

A foo_a;

B foo_b;

A * foo () {
assert ((&foo_b) - *&foo_a) == 1);
return &foo_a;
}

B (const A & x, const A & y) : foo_a(x), foo_b(y) {}
};
Run Code Online (Sandbox Code Playgroud)

甚至使用char foo [2*sizeof(A)]新的位置 - YUK!

当然有一个正确的方法来做到这一点?

Joh*_*itb 5

你可以用boost::array.它内部有一个普通的原生数组,因此它仍然具有与您的示例中相同的内存布局.

struct B {
 boost::array<A, 2> foo;

 B (const A & x, const A & y)
 : foo(createFoo(x, y))
 {}

private:
 static boost::array<A, 2> createFoo(const A & x, const A & y) {
   boost::array<A, 2> a = {{ x, y }};
   return a;
 }
};
Run Code Online (Sandbox Code Playgroud)

如果你没有boost,你可以创建自己的array类,或者std::tr1如果你的编译器有它

template<typename T, std::size_t N>
struct array {
  T data[N];
};
Run Code Online (Sandbox Code Playgroud)

这就是你所需要的,但你可以添加常用的begin,end,size等功能,使之更加舒适的使用.


Cha*_*via 4

不幸的是,确实没有适当、干净的方法来做到这一点。将其视为某种语言限制,是由 C++ 构造函数和 C 样式数组的尴尬混合造成的。C++11 标准解决了这个问题,但在此之前您将不得不寻求解决方法。

由于A没有默认构造函数,一种可能的解决方法是使用一个A*指针数组,然后循环该数组并使用 初始化每个指针new。(显然,不要忘记deleteB 的析构函数中数组中的每一项,或者只使用智能指针。)

  • 您是否读过 spraff 写的“我在 GCC4.3 中使用 C++0x 支持,据称它支持初始化列表”_? (2认同)