交换算法赋予所有相同的值

Swapping algorithm giving everything the same value

我的课程任务是编写一个程序,创建 52 个纸牌对象,每张纸牌都有一个值和一套花色。创建对象数组后,我们必须随机切换两张卡片的位置。问题是,当我去交换我的卡片时,结果发现它们是一样的。这是导致问题的代码:

void SwapCards(Card* cardOne, Card* cardTwo) {
    //swap cards here
    Card *temp = cardOne;
    *cardOne = *cardTwo;
    *cardTwo = *temp;
    //once it gets here all three variables end up with the same object?
}

下面是调用此函数的 for 循环:

for (int i = 0; i < 104; i++) { 
    //get two random values and send them to SwapCards to switch both objects
    int c_one = RandomRange(0, 51);
    int c_two = RandomRange(0, 51);
    SwapCards(deck[c_one], deck[c_two]);
}

如有任何帮助,我们将不胜感激。我花了很多时间试图弄明白,但它让我很困惑。

Card *temp = cardOne; 中的 temp 中删除 *。而是使用

Card temp = *cardOne;

然后

*cardTwo = temp;

"The problem is when I go to swap my cards that they both turn out to be the same."

您正在丢失 cardOne 的当前值:

*cardOne = *cardTwo;

因为 temp 仍然指向与 cardOne 相同的地址,cardOne 的原始值没有被保存。

按如下方式更改您的代码,以保存 cardOne 的值:

Card temp = *cardOne;
*cardOne = *cardTwo;
*cardTwo = temp;

更好(也可能更清晰)的解决方案是使用引用而不是指针:

void SwapCards(Card& cardOne, Card& cardTwo) {
    //swap cards here
    Card temp = cardOne;
    cardOne = cardTwo;
    cardTwo = temp;
}

附带说明:这是 std::swap() 已经做的,不需要在这里推出您自己的实现。

进入函数后,cardOne指向一张卡,cardTwo指向另一张卡

 Card *temp = cardOne;

temp 现在指向 cardOne 指向的卡片。

 *cardOne = *cardTwo;

cardOne指向的卡现在与cardTwo指向的卡具有相同的值。

 *cardTwo = *temp;

cardTwo 指向的卡现在与 temp 指向的卡具有相同的值,这是 cardOne 指向的同一张卡 - 您只是给出了与 cardTwo 指向的卡片相同的值。
换句话说,这为 *cardTwo 分配了与 *cardTwo 已经具有的值相同的值。

对于交换,您要保存 *cardTwo 的值,而不是其地址。

Card temp = *cardOne;
*cardOne = *cardTwo;
*cardTwo = temp;

在 C++ 中编写 "swap" 函数的标准方法是传递 引用 而不是指针:

void swap(Card &a, Card &b)
{
    Card tmp(a);  // or Card tmp = a;
    a = b;
    b = tmp;
}

不需要调用函数 swapCard 因为参数匹配意味着它只能用两个 Card 参数调用。

然后可以使用模板使其几乎完全通用:

template <class T> void swap ( T& a, T& b )
{
    T tmp(a);  // construct a copy of a
    a = b;     // overwrite 'a'
    b = c;     // replace 'b' with the copy
}

这是一个如此普遍的范例,以至于它成为了标准 - std::swap

如果 T 类型与 "just works" 兼容,否则您可以为特定 class 实施 "specialization" 模板。有时出于效率原因需要专门化(例如,您可以交换成员指针而不是复制它们的内容)。