C++ 初始化对象数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7558280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Initializing an array of objects
提问by Stephen Collins
I'm currently working on a card game, and I'm having trouble with some initialization code:
我目前正在开发一款纸牌游戏,但在处理一些初始化代码时遇到了问题:
// in my class...
Card cards[20];
// in method...
for(int i = 0; i <= 20;i++)
cards++ = new Card(i, /*i as char +*/ "_Card.bmp");
The trouble is that my compiler's telling me that cards++
is not an l-value. I've read up on the whole pointer-array equivalence thing, and I thought I understood it, but alas, I can't get it to work. My understanding is that since cards
degrades to a pointer, and the new
operator gives me a pointer to the location of my new instance of Card, then the above code should compile. Right?
问题是我的编译器告诉我这cards++
不是一个左值。我已经阅读了整个指针数组等效性的内容,我以为我理解了它,但是唉,我无法让它工作。我的理解是,由于cards
降级为指针,并且new
运算符给了我一个指向我的新 Card 实例位置的指针,那么上面的代码应该可以编译。对?
I've tried using a subscript as well, but isn't cards+i
, cards++
, and cards[i]
just 3 ways of saying the same thing? I thought that each of those were l-values and are treated as pointers.
我也试过使用下标,但不是cards+i
, cards++
, 和cards[i]
3 种说法吗?我认为每个都是 l 值并被视为指针。
回答by Mahesh
Card cards[20];
cards
is already an array of objects. They are constructed with the default constructor(constructor with no arguments). There is no need to new
again. Probably you need a member function equivalent to constructor arguments and assign through it.
cards
已经是一个对象数组。它们是用默认构造函数(没有参数的构造函数)构造的。没有必要new
再次。可能您需要一个等效于构造函数参数的成员函数并通过它进行分配。
for ( int i=0; i<20; ++i ) // array index shouldn't include 20
cards[i].memberFunction(/*....*/);
Even simpler is to use std::vector
更简单的是使用 std::vector
std::vector<Card> cards;
for( int i=0; i<20; ++i )
cards.push_back(Card(i, /*i as char +*/ "_Card.bmp"); )
回答by Mark B
The code Card cards[20];
already creates an array of 20 Card
objects and creates them with the default constructor. This may not be what you want given your code.
代码Card cards[20];
已经创建了一个包含 20 个Card
对象的数组,并使用默认构造函数创建它们。鉴于您的代码,这可能不是您想要的。
I would suggest using vector
instead.
我建议vector
改用。
std::vector<Card> cards;
for(int i = 0; i < 20;i++)
{
cards.push_back(Card(i, /*i as char +*/ "_Card.bmp"));
}
Note that your for
loop goes from 0
to 20
and thus one past the end of the array.
请注意,您的for
循环从0
to 开始20
,因此越过数组的末尾。
回答by Pr0methean
If you want to avoid unnecessary constructor calls andunnecessary resizing, then it's more complicated, because C++ normally initialises each objects one-by-one as it's allocated. One workaround is to do it the Java way -- use a loop and an array of pointers, like so:
如果你想避免不必要的构造函数调用和不必要的调整大小,那就更复杂了,因为 C++ 通常在分配每个对象时一一初始化。一种解决方法是使用 Java 方式进行操作——使用循环和指针数组,如下所示:
Card *cards[20];
for (int i=0; i<20; i++) {
cards[i] = new Card(i);
}
Another option is to use malloc to get explicitly uninitialized memory:
另一种选择是使用 malloc 来获取显式未初始化的内存:
Card *cards = malloc(20 * sizeof(Card));
for (int i=0; i<20; i++) {
new (&(cards[i])) Card(i);
}
回答by Vaishak Nair
An array name, cards
in your code, contains the addressof the first element of the array. Such addresses are allocated at run time and you cannot change them. Hence the compiler complaining about cards
being not an l-value.
cards
代码中的数组名称包含数组第一个元素的地址。此类地址是在运行时分配的,您无法更改它们。因此编译器抱怨cards
不是左值。
But you can definitely specify what those addresses can hold by using a pointer like below:
但是您绝对可以使用如下所示的指针指定这些地址可以保存的内容:
// in my class...
Card cards[20];
Card *cardsPointer = cards;// Pointer contains the address of the
//1st element of 'cards' array.
// in method...
for(int i = 0; i < 20; i++)
*(cardsPointer++) = Card(i, /*i as char +*/ "_Card.bmp");// Note that
// there is no 'new' operator as 'cardsPointer' has type 'Card *' and
// not 'Card **'. And 'cardsPointer' has type 'Card *' as the array is
// of type 'Card'.
回答by Iziminza
Well, there is another possibility, when you are ok with your constructors being called automatically at initialization:
好吧,还有另一种可能性,当您在初始化时自动调用构造函数时没问题:
// in my class...
Card cards[20] = { Card(0, "0_Card.bmp"), Card(1, "1_Card.bmp"), /* ... */ };
The huge downside is that you cannot use a loop in this case.
最大的缺点是在这种情况下不能使用循环。