This question already has answers here:
Object array initialization without default constructor

(11个答案)


6年前关闭。




我想初始化一个结构类型的数组。目前我正在这样做
struct Gene
{
    int **boxes;
    int fitness;

    Gene()
    {
        boxes = new int*[get_the_number];
        for (int i = 0; i < get_the_number; ++i) {
            boxes[i] = new int[get_the_number];
        }
    }
};

我正在这样初始化
Gene * P = new Gene [t];

它工作正常,我可以做我的工作。它调用了我自己编写的默认构造函数,并且工作已完成。但是现在,我想将参数传递给默认构造函数。我将构造函数更改为此。
Gene(int n)

但是我不知道如何初始化它
Gene * P= new Gene (2) [t];

但这给我一个错误,即“不存在从Gene *到Gene的适当转换”。我知道我可以编写setter函数并在那里做我想做的事情,或者代替生成Gene类型的数组,我可以创建Gene *的数组,并在每个索引处都可以初始化new Gene(2)。但是我不想做,因为我不需要传递变量。我只是想知道我不能调用带有参数的构造函数。

我不能做类似Gene * P= new Gene(2)[t];的事情吗?

我的意思是编译器正在调用不带参数的构造函数。它不能叫这个构造函数吗?
谢谢,

附注:我知道这是一个初学者的问题,但是很长一段时间后我又回到了C++,所以我不会安静地记住事情。

最佳答案

首先,我会建议不要使用std::vectornew[],而是使用delete[]。您将省去很多麻烦。

第二,我可以想出一种方法来做我想做的事情。我无法想象如果使用不同的参数(类似于Lisp的map)创建每个对象,您会期望什么样的语法,所以我将假设您希望使用相同的参数创建每个对象,或者具有易于计算的参数。

带有所有相同对象的std::vector:

#include <vector>

std::vector<Gene> P(size, Gene(2));

带有相似但不相同对象的std::vector:
#include <algorithm>
#include <iterator>
#include <vector>

int foo = 0;
std::vector<Gene> P;
// you can omit the next line; back_inserter will make sure the vector grows appropriately
P.reserve(size);
std::generate_n(std::back_inserter(P), size, [&foo](){ Gene(++foo); });

您可以在创建Gene对象的lambda中获得更多的选择,或者可以使用常规函数代替lambda。

具有相同对象的new []:
#include <algorithm>
#include <iterator>

Gene* P = new Gene[size];
std::fill_n(P, size, Gene(2));

具有类似对象的new []:
#include <algorithm>
#include <iterator>

int foo = 0;
Gene* P = new Gene[size];
std::generate_n(P, size, [&foo]() { Gene(++foo); });

两种使用new[]的情况都创建了默认对象,这些默认对象立即被fill_ngenerate_n覆盖(在不错的实现中,vector方法应该不会出现此问题)。不必担心,但是我有义务提起它。更大的问题是用纯new[]delete[]编写异常安全代码几乎是不可能的。用vector编写异常安全代码要容易得多。

而且,是的,出于相同的原因,我会建议对Gene进行相同类型的更改(到目前为止,Gene根本不是异常安全的;鉴于new[]通过抛出异常报告失败,这是很糟糕的):
#include <algorithm>
#include <iterator>
#include <vector>

struct Gene {
    std::vector<std::vector<int>> boxes;
    int fitness;
    static const size_t DEFAULT_NUMBER_OF_BOXES = 20;

    Gene() : boxes(DEFAULT_NUMBER_OF_BOXES), fitness(0)
    {
        std::for_each(boxes.begin(), boxes.end(),
                      [](std::vector<int>& b) { b.resize(DEFAULT_NUMBER_OF_BOXES); });
    }

    Gene(size_t N) : boxes(N), fitness(0)
    {
        std::for_each(boxes.begin(), boxes.end(),
                      [N](std::vector<int>& b) { b.resize(N); });
    }
};

关于c++ - 如何用C++中没有默认构造函数的结构体初始化数组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23227794/

10-09 03:18