【发布时间】:2016-04-26 09:25:53
【问题描述】:
我有以下代码sn-p:
#include <iostream>
using namespace std;
class A {
int* data;
int size;
public:
A(int s):size(s)
{
data = new int[size];
}
A() {
data = nullptr;
}
~A() {
if (data) delete [] data;
}
};
class B {
A a[2];
public:
B() {
a[0] = A(10);
a[1] = A(11);
}
};
int main(int argc, char *argv[]) {
B b;
}
在上面的 C++ 代码中,我有 class A,它有一个 array 成员 int* data,并且 (de) 内存分配由 (de) 处理构造函数。我创建了 class B,它有一个固定长度的 class A 的 array 作为数据成员。
我的问题是:如何优雅地初始化成员A a[2]?在上面的代码中,A(10)和A(11)是在栈上创建的,当跳出作用域时,会调用它们的析构函数,因此数据无效。跳转main函数作用域时,a[2]持有的指针会被释放两次,导致报错:
pointer being freed was not allocated。
一种可能的解决方案是仔细设计copy constructor 和move constructor,这样上述编码范例就可以工作。
我尝试过的另一个解决方案是在class B的初始化列表中初始化数组:
B() : a { A(10), A(11) }
这个解决方案有效,我并没有真正告诉初始化列表的底层机制。我想它一定和简单的construct和copy有很大的不同。我真的希望一些专家可以对这种机制进行详细的解释。当然,这个解决方案是丑陋的硬编码并且不灵活。
所以我想知道 C++ 中是否有一些编程范式来解决这个设计问题?
【问题讨论】:
-
在我们跳入任何复杂的东西之前,深入了解
if (data) delete [] data;怎么样——你查过delete []做了什么吗? -
有关范例,请参阅rule of five。如需解决方案,请参阅
std::vector。
标签: c++ arrays initialization