c ++中的空动态数组

假设我有一个名为
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数组,然后再进行构造呢? 编辑:由于代码中的其他内容,这必须是一个数组,这里很难解释。     
已邀请:
你可以创建一个指向
Square
的指针数组:
Square **squares = new Square*[10];

for (int i = 0; i < 10; i++)
{
     squares[i] = new Square(i, i);
}
正如其他人所指出的那样,考虑使用
std::vector
是个好主意。     
使用
vector
。只要
Square
是可复制的,它就没有这个问题。
vector<Square> squares;
for (int i = 0; i < 10; i++)
{
     squares.push_back(Square(i, i));
}
    
标准库容器的工作方式是使用新的放置。只使用像
std::vector
这样的标准库容器绝对是最简单的方法。新位置是最难的。像Xeo所提到的那样,分配单个对象并保持数组中的指针位于中间。     
你应该制作一个指向
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指针容器库。     
在适用的程序中使用
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);
}
当然,需要在使用结束时手动调用析构函数。     
我建议你使用
std::vector
而不是动态分配的数组。
std::vector
s更容易使用,并且不会泄漏内存。 但是,错误消息引用的缺失构造函数是
Square
的构造函数。您需要为不带参数的
Square
添加构造函数。以下之一将做:
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
可以与阵列互换:   为什么矢量是连续的如此重要?因为你需要保证向量与C数组的布局兼容,因此我们没有理由不使用向量作为数组的优越且类型安全的替代,即使我们需要使用C代码交换数据。因此,vector是我们通往其他语言和大多数操作系统功能的门户,其通用语言是古老的C数组。 顺便说一下,语法是(假设
v
是向量)
&v[0]
。也就是说,取第一个元素的地址(并且它是一个引用,因此除了
std::vector<bool>
之外适用于所有ѭ5)并且你将获得一个指针,你可以传递给任何需要指针的函数(你当然可以,得到“数组”的长度为
v.size()
)。     
简单地使用指向指针的指针
Square **squares = new Square*[10];  
它应该工作。但是当你开始使用像vector这样的STL容器时,我猜你真的会变得更好     
使用
std::vector
,或使用相同的技术:使用全局new运算符分配“raw”存储空间,并使用placement new在该存储中创建对象(并通过直接调用dtor而不是使用delete来销毁它们)。     
Square *squares = new Square[10];
此操作调用默认构造函数10次。并且您的代码段中没有一个导致错误。所以,提供一个。只需编写setter方法来初始化类成员。
for (int i = 0; i < 10; i++)
{
     squares[i] = new Square(i, i);
}
通过
new
for
循环中再次操作,你只是泄漏之前获得的记忆但是按照你的想法行事。 另外别忘了在
squares
上拨打
delete[]
。     

要回复问题请先登录注册