我有以下代码片段:
#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 的类,该类具有一个名为
int * data
的数组成员,并且内存的(de)分配由(de)构造函数处理。然后,我创建了一个名为 class B 的类,该类具有固定长度的 class A 数组作为数据成员。
我的问题是:如何优雅地初始化成员 A a [2]
?在上面的代码中, A(10)
和 A(11)
在堆栈上创建,当跳出作用域时,它们的析构函数将被调用,因此数据变得无效。当跳出 main
函数的作用域时, a [2]
持有的指针将被释放两次,导致错误:
释放的指针未被分配
。
一种可能的解决方案是仔细设计复制构造函数
和移动构造函数
,通过这样做,上述编码范例可以正常工作。
我尝试过的另一种解决方案是在 class B
的初始化列表中初始化数组:
B() : a { A(10), A(11) }
这个解决方案可行,但我并没有详细说明初始化列表的底层机制。我认为它肯定与简单的构造和复制非常不同。我真的希望一些专家能够详细解释这个机制。当然,这个解决方案是丑陋的硬编码,并且不够灵活。
所以我想知道在C++中是否有一些编程范式来解决这个设计问题?
if (data) delete [] data;
的含义——你查过delete []
的作用吗? - Kerrek SBstd::vector
以获取解决方案。 - Quentin