有没有办法初始化没有默认构造函数的对象数组?
struct IndexAndSign {
const int depth;
const bool baseIsPositive;
IndexAndSign(int depth, bool baseIsPositive)
: depth(depth)
, baseIsPositive(baseIsPositive) {}
};
void test() {
auto arr = new IndexAndSign[size]; // error
}
基本上你不能。正如您所发现的,当您使用
IndexAndSign* arr = new IndexAndSign[size];
C++ 搜索默认(裸)构造函数来为对象分配正确的内存量。但是由于
const
成员的初始化列表,您无法提供裸构造函数。
但是,也有一些漏洞:
std::vector
”,例如:std::vector<IndexAndSign> arr;
for(int i=size; i-->0;){
int d=0; bool biP=true; // or something
arr.push_back(IndexAndSign(d, bIP));
}
但是,这个解决方案有一个隐藏的问题:它使用了你班级的
move constructor
。而如果你的类有点复杂,编译器提供的默认移动构造函数将会是错误的(根据 n 的规则)。
IndexAndSign** arr = new IndexAndSign*[size];
for(int i=size; i-->0;){
int d=0; bool biP=true; // or something
arr[i] = new IndexAndSign(d, bIP);
}
这个解决方案的缺点是,如果你想访问对象的成员,你必须使用
->
而不是 .
,例如:
std::cout << arr[0]->depth << std::endl;
进一步阅读是这里
是的,如果您使用的是 c++17 或更高版本,这是可行的。您可以使用
std::allocator::allocate
来分配数组并启动数组的生命周期,但不启动数组的对象。然后根据 OP 的注释,在 for 循环中使用 new 放置来初始化数组的对象。
#include <memory>
#include <iostream>
class IndexAndSign {
public:
const int depth;
const bool baseIsPositive;
IndexAndSign(int depth, bool baseIsPositive) : depth(depth), baseIsPositive(baseIsPositive) {}
};
void test() {
size_t size = 10;
IndexAndSign* allSignChangeEdges;
std::allocator<IndexAndSign> my_alloc;
allSignChangeEdges = my_alloc.allocate(size);
// demonstrate intitialization in a for loop
for (size_t i = 0; i < size; i++)
new(allSignChangeEdges + i) IndexAndSign(static_cast<int>(i), true);
// show allSignChangeEdges[4].depth == 4
std::cout << allSignChangeEdges[4].depth << '\n';
// do stuff and cleanup
my_alloc.deallocate(allSignChangeEdges, size);
}
int main()
{
test();
}