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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:07:26  来源:igfitidea点击:

Initializing an array of objects

c++arrays

提问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 cardsdegrades to a pointer, and the newoperator 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];

cardsis already an array of objects. They are constructed with the default constructor(constructor with no arguments). There is no need to newagain. 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 Cardobjects 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 vectorinstead.

我建议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 forloop goes from 0to 20and thus one past the end of the array.

请注意,您的for循环从0to 开始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, cardsin 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 cardsbeing 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.

最大的缺点是在这种情况下不能使用循环。