c++ 中的空动态数组
假设我有一个名为 Square
的对象,其构造函数为 Square(int rx, int ry)
,我想创建一个动态的 Square 数组,在构造函数中具有不同的参数:
Square *squares = new Square[10];
for (int i = 0; i < 10; i++)
{
squares[i] = new Square(i, i);
}
但是这失败了,说没有可用的适当的默认构造函数。那么我如何创建一个空数组或 NULL 数组,然后稍后进行构造?
编辑:这必须是一个数组,由于代码中的其他内容,这里很难解释。
Let's say I have an object called Square
with the constructor Square(int rx, int ry)
, i want to create a dynamic array of Squares, with different arguments in the constructor:
Square *squares = new Square[10];
for (int i = 0; i < 10; i++)
{
squares[i] = new Square(i, i);
}
However this fails, saying no appropriate default constructor available. So how do i create an empty or NULL array and then do constructions later?
EDIT: This has to be an array, due to other things in code, to hard to explain here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
使用
向量
。只要Square
是可复制的,就不存在这个问题。Use
vector
. It doesn't have this problem as long asSquare
is copyable.您可以创建一个指向
Square
的指针数组:正如其他人指出的那样,考虑使用
std::vector
是个好主意。You could make an array of pointers to
Square
:As others have pointed out, it is a good idea to consider using
std::vector
instead.标准库容器的做法是使用新的放置。仅使用标准库容器,例如 std::vector ,绝对是最简单的方法。而新的安置是最难的。分配单个对象并将指针保留在数组中,就像 Xeo 提到的那样,落在中间。
The way the standard library containers do it is with placement new. Just using a standard library container, like
std::vector
, is definitely the easiest way. And placement new is the hardest. Allocating individual objects and keeping pointers in the array, like Xeo mentioned, falls in the middle.您应该创建一个指向
SQuare
的指针数组。但是,我还建议使用
std::vector
而不是“经典”数组,如果Square
是可复制的,这是一个很好的解决方案。但是,如果不是,或者您仍然决定采用指针方式,请将其设为
shared_ptr
的std::vector
,以将所有删除负担留给编译器。这会给出类似的内容:
要更进一步,您可以查看 Boost指针容器库。
You should make an array of pointers to
SQuare
.However, I would also recommend to use a
std::vector
instead of a "classic" array, this is a good solution ifSquare
is copyable.However, if it is not, or if you still decide to go the pointer way, make it a
std::vector
ofshared_ptr
to leave all the deletion burden to the compiler.This would give something like:
To go even further, you could take a look at the Boost Pointer Container library.
如果适用,请在程序中使用
向量
。如果您确实需要使用原始new
,则可以使用placement new。并使用
operator delete(squares);
删除它。请注意,您需要手动调用这些对象的析构函数。或者,您可以使用原始存储迭代器创建对象。当然,在使用结束时手动调用析构函数的需要仍然存在。
Use
vector
in programs where applicable. If you really need to use a rawnew
, you can use placement new.And delete it with
operator delete(squares);
. Notice that you need to manually call the destructors of these objects then. Alternatively, you can create the objects with a raw storage iteratorThe need to manually call the destructors at the end of use stays, of course.
我建议您使用
std::vector
而不是动态分配的数组。std::vector
更容易使用,并且不会泄漏内存。但是,错误消息所指的缺少的构造函数是 Square 的构造函数。您需要为
Square
添加一个不带参数的构造函数。 其中一个即可:请注意,如果您将这两个都放入文件中,那么您将收到错误,因为当没有时,将无法知道要调用哪个构造函数给出了论点。
即使您使用
std::vector
,您也可能需要默认构造函数。 “可能”,因为如果您将自己限制为接受对象的std::vector
构造函数,那么您可以绕过它,例如:我已经将其添加为问题的注释本身。正如 Herb Sutter 所说,
std::vector
是 设计为可与数组互换:顺便说一下,语法是(假设
v
是一个向量)&v[0]
。也就是说,获取第一个元素的地址(它是一个引用,因此适用于除std::vector
之外的所有std::vector
)您将得到一个指针,您可以将其传递给任何需要指针的函数(当然,您可以通过v.size()
获取“数组”的长度)。I would recommend you use a
std::vector
instead of a dynamically-allocated array.std::vector
s are much easier to work with, and don't leak memory.However, the missing constructor the error message refers to is
Square
's constructor. You need to add a constructor forSquare
that takes no arguments. ONE of the following will do:Please note that if you put both of these in the file, then you will get an error, because it will be impossible to know which constructor to call when no arguments are given.
You'll probably want the default constructor even if you use a
std::vector
. "Probably," because you can get around it, if you limit yourself tostd::vector
's constructors that take an object, eg.:I've already added this as a comment to the question itself. As Herb Sutter says,
std::vector
is designed to be interchangeable with arrays:The syntax, by the way is (assuming
v
is a vector)&v[0]
. That is, take the address of the first element (and it's a reference, so that works on allstd::vector
s except forstd::vector<bool>
) and you'll get a pointer that you can pass to any function that expects a pointer (you can, of course, get the length of the "array" asv.size()
).简单地使用一个指向指针的指针
,它应该可以工作。但我想当你开始使用像矢量这样的 STL 容器时,你的情况真的会更好
Simple use a pointer to a pointer
And it should work. But I guess you are really better off when you start using STL containers like vector
使用 std::vector ,或使用与它相同的技术:使用全局 new 运算符分配“原始”存储空间,并使用placement new 在该存储中创建对象(并通过调用 dtor 销毁它们)直接而不是使用删除。
Use
std::vector
, or use the same technique it does: allocate "raw" storage space with the global new operator, and create objects in that storage using placement new (and destroy them by invoking the dtor directly instead of using delete.此操作调用默认构造函数 10 次。并且您的代码片段中没有一个导致错误。所以,提供一个。只需编写setter方法来初始化类成员。
通过在
for
循环中再次进行new
操作,您只是泄漏了之前获取的内存,但做了您所想的事情。另外,不要忘记在
squares
上调用delete[]
。This operation calls the default constructor 10 times. And there is not one in your snippet resulting error. So, provide one. Just write setter method to initialize class members.
By
new
operation again in thefor
loop, you are just leaking the memory acquired before but does what you think.Also don't forget to call
delete[]
onsquares
.