初始化对象数组

Initializing an array of objects

本文关键字:数组 对象 初始化      更新时间:2023-10-16

我目前正在制作一款纸牌游戏,我遇到了一些初始化代码的问题:

// in my class...
Card cards[20];
// in method...
for(int i = 0; i <= 20;i++)
    cards++ = new Card(i, /*i as char +*/ "_Card.bmp");

问题是我的编译器告诉我cards++不是l值。我读过指针数组等价的所有东西,我以为我理解它,但是,唉,我不能让它工作。我的理解是,由于cards降级为指针,并且new操作符给了我一个指向我的新Card实例位置的指针,那么上面的代码应该编译。对吧?

我也试过使用下标,但不是cards+i, cards++cards[i]只是说同一件事的3种方式?

Card cards[20];

cards已经是一个对象数组。它们是用默认构造函数(没有参数的构造函数)构造的。没有必要再执行new。可能需要一个相当于构造函数参数的成员函数,并通过它进行赋值。

for ( int i=0; i<20; ++i ) // array index shouldn't include 20
   cards[i].memberFunction(/*....*/);
更简单的是使用std::vector
std::vector<Card> cards;
for( int i=0; i<20; ++i )
    cards.push_back(Card(i, /*i as char +*/ "_Card.bmp"); )

代码Card cards[20];已经创建了一个包含20个Card对象的数组,并使用默认构造函数创建它们。对于你的代码,这可能不是你想要的。

我建议用vector代替。

std::vector<Card> cards;
for(int i = 0; i < 20;i++)
{
    cards.push_back(Card(i, /*i as char +*/ "_Card.bmp"));
}

请注意,您的for循环从020,因此超过了数组的末尾。

如果您想避免不必要的构造函数调用不必要的调整大小,那么它就更复杂了,因为c++通常在分配对象时逐个初始化每个对象。一种解决方法是使用Java方法——使用循环和指针数组,如下所示:

Card *cards[20];
for (int i=0; i<20; i++) {
  cards[i] = new Card(i);
}

另一个选项是使用malloc来显式获取未初始化的内存:

Card *cards = malloc(20 * sizeof(Card));
for (int i=0; i<20; i++) {
  new (&(cards[i])) Card(i);
}

嗯,还有另一种可能性,当您同意在初始化时自动调用构造函数时:

// in my class...
Card cards[20] = { Card(0, "0_Card.bmp"), Card(1, "1_Card.bmp"), /* ... */ };

数组名称(代码中的cards)包含数组第一个元素的地址。这些地址是在运行时分配的,您不能更改它们。因此,编译器抱怨cards不是l值。

但是你可以使用指针来指定这些地址可以保存的内容,如下所示:

// 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'.