假设我有一个名为Square
的对象,带有构造函数Square(int rx, int ry)
,我想创建一个Squares的动态数组,在构造函数中有不同的参数:
Square *squares = new Square[10];
for (int i = 0; i < 10; i++)
{
squares[i] = new Square(i, i);
}
然而,这失败了,说没有合适的默认构造函数。那么我如何创建一个空数组或NULL数组然后再构建 ?
编辑:由于代码中的其他内容,这必须是一个数组,这里难以解释。
答案 0 :(得分:7)
使用vector
。只要Square
可以复制,它就没有这个问题。
vector<Square> squares;
for (int i = 0; i < 10; i++)
{
squares.push_back(Square(i, i));
}
答案 1 :(得分:5)
您可以将指针数组创建为Square
:
Square **squares = new Square*[10];
for (int i = 0; i < 10; i++)
{
squares[i] = new Square(i, i);
}
正如其他人所指出的,最好考虑使用std::vector
代替。
答案 2 :(得分:1)
你应该制作一个指向SQuare
的指针数组。
但是,我还建议使用std::vector
而不是“经典”数组,如果Square
可以复制,这是一个很好的解决方案。
但是,如果不是,或者您仍然决定使用指针方式,请将其设为std::vector
shared_ptr
,以便为编译器留下所有删除负担。
这会产生类似的结果:
#include <vector>
#include <boost/shared_ptr.hpp> //on some compilers, you can use #include <memory> instead
using std::vector;
using boost::shared_ptr; // or using std::shared_ptr
vector<shared_ptr<Square> > squares(10);
for (int i = 0; i < 10; i++)
{
squares[i].reset(new Square(i, i));
}
为了更进一步,您可以查看Boost Pointer Container library。
答案 3 :(得分:1)
标准库容器的工作方式是使用placement new。只使用标准库容器,如std::vector
,绝对是最简单的方法。新位置是最难的。像Xeo所提到的那样,分配单个对象并保持数组中的指针位于中间。
答案 4 :(得分:1)
在适用的程序中使用vector
。如果您确实需要使用原始new
,则可以使用展示位置新功能。
Square *squares = static_cast<Square*>(operator new(sizeof(*squares) * 10));
for (int i = 0; i < 10; i++) {
new (static_cast<void*>(squares + i)) Square(i, i);
}
并使用operator delete(squares);
删除它。请注意,您需要手动调用这些对象的析构函数。或者,您可以使用原始存储迭代器
std::raw_storage_iterator<Square*, Square> rsi(squares);
for (int i = 0; i < 10; i++) {
*rsi++ = Square(i, i);
}
当然,需要在使用结束时手动调用析构函数。
答案 5 :(得分:1)
我建议您使用std::vector
而不是动态分配的数组。 std::vector
更容易使用,并且不会泄漏内存。
但是,错误消息引用的缺少的构造函数是Square
的构造函数。您需要为Square
添加一个不带参数的构造函数。以下 ONE 会:
class Square {
Square() { ... }
// Square with dimensions of 0 is empty
Square(int length=0, int width=0) { ... }
...
};
请注意,如果你将这两个文件放在文件中,那么你会收到一个错误,因为当没有给出参数时,无法知道要调用哪个构造函数。
即使您使用std::vector
,也可能需要默认构造函数。 “可能,”因为你可以绕过它,如果你把自己限制在接受一个对象的std::vector
构造函数中,例如:
std::vector<Square> foo(10, Square(0, 0));
// reassign each element accordingly
我已经将此添加为对问题本身的评论。正如Herb Sutter所说,std::vector
是designed to be interchangeable with arrays:
为什么矢量是连续的如此重要?因为你需要保证向量与C数组的布局兼容,因此我们没有理由不使用向量作为数组的优越且类型安全的替代,即使我们需要使用C代码交换数据。因此,vector是我们通往其他语言和大多数操作系统功能的门户,其通用语言是古老的C数组。
顺便说一句,语法是(假设v
是向量)&v[0]
。也就是说,取第一个元素的地址(并且它是一个引用,因此除std::vector
之外的所有std::vector<bool>
都有效),你将得到一个指针,你可以传递给任何函数需要一个指针(当然,您可以将“数组”的长度设为v.size()
)。
答案 6 :(得分:0)
简单地使用指向指针的指针
Square **squares = new Square*[10];
它应该有效。但是当你开始使用像vector
这样的STL容器时,我想你真的会更好答案 7 :(得分:0)
使用std::vector
,或使用相同的技术:使用全局new运算符分配“原始”存储空间,并使用placement new在该存储中创建对象(并通过直接调用dtor而不是使用删除。
答案 8 :(得分:0)
Square *squares = new Square[10];
此操作调用默认构造函数 10 次。并且您的代码段中没有一个导致错误。所以,提供一个。只需编写setter方法来初始化类成员。
for (int i = 0; i < 10; i++)
{
squares[i] = new Square(i, i);
}
在new
循环中再次进行for
操作,您只是泄漏了之前获得的内存,但却按照您的想法行事。
另请不要忘记在delete[]
上致电squares
。