如果类(class)中我们指定了带参数的构造函数(constructor),那么一般在创建该对象类型的数组时是没法给定构造参数的,就是说无法调用到我们指定的构造函数,如下:
class Foo {
public:
Foo(int ID);
int getId();
private:
int ID;
};
Foo::Foo(int ID) {
this->ID = ID;
}
int Foo::getId() {
return ID;
}
int main () {
Foo *foos = new Foo[10]; //错误,没有正确调用到构造函数
//...
}
我们可以在定义数组时直接初始化,这样可以给定构造参数,例如:
int ID1, ID2, ID3, .... , ID10;
Foo *foos = {
new Foo(ID1),
new Foo(ID2),
...
new Foo(ID10)
};
这样可以,但是如果我们想要在堆中动态分配数组那怎么办呢?这里就要用到operator new[]函数(注意,这是函数,不是操作符),它的用法:operator new[] (size_t m)
。
如下:
void *raw = operator new[] (10 * sizeof(Foo));
Foo *foos = static_cast<Foo*> (raw);
for (int i = 0; i < 10; i++) {
new (&foos[i]) Foo (ID); //注意这种用法,可以直接将数组中对应元素对象调用构造函数构造。
}
还有一种思路就是构建指针数组,然后调用构造函数构造:
void *raw = operator new[] (10 * sizeof(Foo*));
Foo **pfoos = static_cast<Foo**> (raw);
for (int i = 0; i < 10; i++) {
pfoos[i] = new Foo(ID);
}
对比这两种方式,很有意思,尤其前一种方式的用法(这种方式叫做placement new)。
注意这种方式要手动释放内存,需要两步,第一步:
//与构造顺序相反
for (int i = 9; i >= 0; --i) {
foos[i].~Foo();
}
第二步:
//释放raw指针
operator delete[] raw;