我想初始化一个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 ++,所以我不记得了。
答案 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。
#include <algorithm>
#include <iterator>
Gene* P = new Gene[size];
std::fill_n(P, size, Gene(2));
带有类似对象的#include <algorithm>
#include <iterator>
int foo = 0;
Gene* P = new Gene[size];
std::generate_n(P, size, [&foo]() { Gene(++foo); });
new[]
的两个案例都会创建立即用fill_n
或generate_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());