我有一张卡片,可以存储2个代表等级和套装的整数。我有一个类Deck,它包含存储在Array中的52个Card对象。当我初始化牌组时,我创建了所有52张牌并添加到牌组中。
当我这样做时,我应该使用
deck[i] = Card (rank, suit);
或
deck[i] = new Card (rank, suit);
为什么我要使用其中一个?
答案 0 :(得分:5)
如果deck
是Card
的数组,那么您需要第一个:deck[i] = Card (rank, suit);
如果deck
是Card*
的数组,那么您需要第二个:deck[i] = new Card (rank, suit);
答案 1 :(得分:3)
因为一个有效,一个不是。
如果您的数组包含对象,
deck[i] = Card (rank, suit);
有效。
如果您的数组包含指向对象的指针,
deck[i] = new Card (rank, suit);
有效。
如果您尝试编译,您会发现其中一个错误。另一个是你想要的。
答案 2 :(得分:3)
如果您为每种情况适当地声明deck
数组,则您建议的两个选项都有效。让我来讨论每个选项的好处:
deck[i] = Card (rank, suit);
Card
类很简单,编译器生成的默认复制和赋值逻辑就足够了,你可以使用Card
实例,就像它们是一个基本类型一样分配它们或将它们作为参数传递。 deck[i] = new Card (rank, suit);
Card
实例有多大,同样用于在不同数组之间移动卡。与其他情况相比,按值移动Card
实例需要将类的全部内容从内存中的一个位置复制到另一个位置。在我看来,这两种方法都没有明显的优势,如果Card
类如此之小,则更是如此。我可能会自己使用指针,但使用对象也不是一个糟糕的选择。
答案 3 :(得分:2)
在这种情况下,使用Card
数组或Card*
数组有利有弊。
对于指针数组,您需要在删除数组之前手动删除每个指针(以防止内存泄漏)。这也会占用内存中非常小的空间。
作为一个优点,例如,交换两个卡很容易,因为你只需交换指针。
如果你有对象,要交换你需要修改它们或构造新对象(这可能很昂贵)。如果你选择指针,甲板也可以共享牌(我不知道为什么你会在这种特殊情况下使用它,但是为了普遍性而需要注意)。
如果你有一个对象数组,你不需要担心内存管理,但你会失去这种快速交换能力。
这取决于你评估哪一个更适合应用程序,但我个人认为你可以使用对象数组。
答案 4 :(得分:1)
如果您声明了一个Card
项的数组,那么在分配数组时,这些项将是默认构造的,然后您必须返回并使用新的项更新单个Card
项之后的价值观,例如:
Card deck[52];
for (int i = 0; i < 52; ++i)
{
rank = ...;
suit = ...;
deck[i] = Card(rank, suit);
// better, add a method to the `Card` class to
// update the values without constructing any
// temporary instances at all...
//
// deck[i].set(rank, suit);
}
如果声明一个Card
指针数组,那么您可以使用Card
构造函数初始化每个Card
项目所需的值,但代价是分配一个单独的内存每个Card
项的块,例如:
Card* deck[52];
for (int i = 0; i < 52; ++i)
{
rank = ...;
suit = ...;
deck[i] = new Card(rank, suit);
}
如果您使用std::vector
而不是数组,则可以将两者结合使用,例如:
std::vector<Card> deck(52);
for (int i = 0; i < 52; ++i)
{
rank = ...;
suit = ...;
deck[i] = Card(rank, suit);
// or:
// deck[i].set(rank, suit);
}
如果您使用placement new
运算符,那么您实际上可以使用'new'运算符来调用Card
构造函数,而无需为每个Card
分配单独的内存块,而无需默认构造,然后单独复制 - 分配Card
值,例如:
unsigned char deck_buffer[sizeof(Card) * 52];
Card *deck = (Card*) deck_buffer;
for (int i = 0; i < 52; ++i)
{
rank = ...;
suit = ...;
new (&deck[i]) Card(rank, suit);
}