在没有默认构造函数的情况下初始化对象数组

问题描述 投票:0回答:2

有没有办法初始化没有默认构造函数的对象数组?

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
}
c++ arrays default-constructor
2个回答
0
投票

基本上你不能。正如您所发现的,当您使用

IndexAndSign* arr = new IndexAndSign[size];

C++ 搜索默认(裸)构造函数来为对象分配正确的内存量。但是由于

const
成员的初始化列表,您无法提供裸构造函数。

但是,也有一些漏洞:

  1. 默认的新手提示是“use
    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规则)。

  1. 您可以尝试一下指针到指针的概念
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;

进一步阅读是这里


0
投票

是的,如果您使用的是 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();
}
© www.soinside.com 2019 - 2024. All rights reserved.