如何在C ++中使用非默认构造函数初始化结构的数组

时间:2014-04-22 18:47:09

标签: c++ arrays constructor

我想初始化一个struct类型的数组。目前我在做这个

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];之类的事情吗?

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

p.s。:我知道它是一个初学者的问题,但是很长一段时间后我又回到了C ++,所以我不记得了。

5 个答案:

答案 0 :(得分:3)

首先,我建议使用std::vector而不是自己调用new[]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根本不是例外安全;鉴于{{1}通过抛出异常来报告失败):

new[]

答案 1 :(得分:2)

没有简单的方法可以做到这一点,new[]只允许默认或不允许初始化 您可以拥有for并初始化它们(这听起来像最简单的解决方案),但也有更复杂的方法来创建内存对象(void*)并使用{{ 1}}将它们转换为reinterpret_cast,但最后你还需要为每个创建的类实例调用c-tors

答案 2 :(得分:2)

你在做什么可能不是你想要的。你有充分的理由真正使用所有这些指针吗?有一个原因std::vector被发明和最佳实践(因为这似乎是一个初学者的问题,这似乎相关)要求你开始使用一些C ++善良而不是那些讨厌的C指针。

使用std::vector,您可以指定希望向量使用的默认元素:

Gene gene(<some gene constructor call here>);

以下vector constructor call构建了具有17个相同拷贝gene

的基因载体
std::vector<Gene> gene_pool(17, gene); 

p.s。:如果您在编译时甚至知道vector / array / list / container的大小,正如其他人所建议的那样,请查看std::array

答案 3 :(得分:2)

如果您想在代码中避免使用新/删除:

#include <vector>

class Gene
{
    public:
    std::size_t extent;
    std::vector<int> boxes;

    Gene(int n) : extent(n), boxes(n*n, int(0)) {}
    int operator () (unsigned row, unsigned col) {
        return boxes[row * extent + col];
    }
};


int main()
{
    std::size_t t = 42;
    std::vector<Gene> P(t, Gene(2));
    return 0;
}

注意:每个基因在构建后都有自己的框(初始化为零)。

答案 4 :(得分:-3)

首先,除非你真的不知道数组的大小,否则不要使用new。

如果使用静态数组,则可以使用数组的初始化列表:

Gene array[x] = {Gene()};

或者,您可以使用memcpy:

Gene default;
for (int i=0; i < size; i++} 
{
   memcpy (&(array[i]), &default, sizeof(Gene));
}

第三种选择是使用向量

std::vector<Gene> array(size, Gene());