另一个类的Friend类函数? 我试图在C++中编程一个德克萨斯HOLDEM游戏作为练习。我刚刚开始阅读有关好友函数的内容,并考虑使用它们允许玩家从牌堆中抽牌

另一个类的Friend类函数? 我试图在C++中编程一个德克萨斯HOLDEM游戏作为练习。我刚刚开始阅读有关好友函数的内容,并考虑使用它们允许玩家从牌堆中抽牌,c++,C++,我目前定义了两个类,如下所示: #include <string> #include <vector> #include <stdio.h> typedef unsigned int uint; class deck { private: std::vector<card> cards; public: void initialize(void) { char suits[] = { 'H', '

我目前定义了两个类,如下所示:

#include <string>
#include <vector>
#include <stdio.h>
typedef unsigned int uint;    

class deck

{
private:
    std::vector<card> cards;
public:
    void initialize(void)
    {
        char suits[] = { 'H', 'C', 'D', 'S' };
        uint values[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
        for (uint i = 0; i != 4; i++)
        {
            for (uint j = 0; j != 13; j++)
            {
                cards.push_back(card(suits[i], values[j]));
            }
        }
    }
    void shuffle(void)
    {
        uint i = cards.size(), random_index;
        card shuffled_card;
        while (i > 0)
        {
            random_index = rand() % (i + 1);
            shuffled_card = cards[random_index];
            cards[random_index] = cards[i];
            cards[i] = shuffled_card;
            i--;
        }
    }
};

class player
{
private:
    std::string name;
    uint chips;
    std::vector<card> hand;
public:
    player(std::string set_name, uint set_chips) { name = set_name; chips = set_chips; }
    void draw(deck& target_deck, uint number)
    {
        // Draw cards from the top of the 
        // target deck.
    }
};
然而,这并不能解决问题。代码是否有问题,或者唯一的解决方案是(a)在
播放器
之外定义友元函数,还是(b)使整个
播放器
成为
牌组
的a类友元


提前感谢您的指点

我将通过提供一个公共函数
deck::draw()
来解决这个问题,该函数从牌组中返回最上面的牌(并将其从牌组中移除)。然后,您可以根据需要多次调用它,以
deck::draw()
的形式实现
player::draw()

如果您实现了一个
deck::draw()
,那么您可能需要
deck::initialize()
在将52张新卡推到其上之前清除该卡组


作为一种次要的风格注释,在C++中支持“不使用参数的函数”的参数列表中的“代码>空格<代码>,它与C++的向后兼容,但在新C++代码中不常用。C支持它的原因是因为函数声明(prototype)

foo()
没有说明函数采用的参数,而
foo(void)
表示函数不采用参数。C++总是处理<代码>()/<代码>,不接受任何参数。< /P> < P>我将通过提供公共函数<代码>::()(Debug)> /Cuff>来解决这个问题,它从顶层返回顶部卡片(并将其从甲板上删除)。然后,您可以根据需要多次调用它,以
deck::draw()
的形式实现
player::draw()

如果您实现了一个
deck::draw()
,那么您可能需要
deck::initialize()
在将52张新卡推到其上之前清除该卡组


作为一种次要的风格注释,在C++中支持“不使用参数的函数”的参数列表中的“代码>空格<代码>,它与C++的向后兼容,但在新C++代码中不常用。C支持它的原因是因为函数声明(prototype)

foo()
没有说明函数采用的参数,而
foo(void)
表示函数不采用参数。C++总是对待<代码>()/<代码>,不接受任何参数。

你必须在甲板前放<代码>玩家<代码>定义。在定义
deck
类之后,还可以尝试定义
draw
函数

#include <string>
#include <vector>
#include <stdio.h>
typedef unsigned int uint;    

class deck;

class player
{
private:
    std::string name;
    uint chips;
    std::vector<card> hand;
public:
    player(std::string set_name, uint set_chips) { name = set_name; chips = set_chips; }
    void draw(deck& target_deck, uint number); // define it outside.

};


class deck    
{
private:
    std::vector<card> cards;
public:
    friend void draw(deck& target_deck, uint number);
    void initialize(void)
    {
        char suits[] = { 'H', 'C', 'D', 'S' };
        uint values[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
        for (uint i = 0; i != 4; i++)
        {
            for (uint j = 0; j != 13; j++)
            {
                cards.push_back(card(suits[i], values[j]));
            }
        }
    }
    void shuffle(void)
    {
        uint i = cards.size(), random_index;
        card shuffled_card;
        while (i > 0)
        {
            random_index = rand() % (i + 1);
            shuffled_card = cards[random_index];
            cards[random_index] = cards[i];
            cards[i] = shuffled_card;
            i--;
        }
    }
};

 void player::draw(deck& target_deck, uint number)
 {
      // Draw cards from the top of the 
      // target deck.
 }
#包括
#包括
#包括
typedef无符号整数单元;
舱面;
职业选手
{
私人:
std::字符串名;
集成电路芯片;
病媒手;
公众:
播放器(std::string set_name,uint set_chips){name=set_name;chips=set_chips;}
虚线绘制(甲板和目标甲板,uint编号);//在外部定义它。
};
甲板
{
私人:
向量卡;
公众:
朋友无效提款(甲板和目标甲板,uint编号);
void初始化(void)
{
字符匹配[]={'H','C','D','S'};
uint值[]={2,3,4,5,6,7,8,9,10,11,12,13,14};
对于(uint i=0;i!=4;i++)
{
对于(uint j=0;j!=13;j++)
{
卡片。推回(卡片(适合[i],值[j]);
}
}
}
无效洗牌(无效)
{
uint i=cards.size(),随机索引;
洗牌卡;
而(i>0)
{
随机指数=rand()%(i+1);
洗牌牌=牌[随机索引];
卡片[随机指数]=卡片[i];
卡片[i]=洗牌卡片;
我--;
}
}
};
无效玩家::抽牌(牌组和目标牌组,单位号码)
{
//从顶部抽牌
//目标甲板。
}

你必须把
玩家的定义放在牌组之前。在定义
deck
类之后,还可以尝试定义
draw
函数

#include <string>
#include <vector>
#include <stdio.h>
typedef unsigned int uint;    

class deck;

class player
{
private:
    std::string name;
    uint chips;
    std::vector<card> hand;
public:
    player(std::string set_name, uint set_chips) { name = set_name; chips = set_chips; }
    void draw(deck& target_deck, uint number); // define it outside.

};


class deck    
{
private:
    std::vector<card> cards;
public:
    friend void draw(deck& target_deck, uint number);
    void initialize(void)
    {
        char suits[] = { 'H', 'C', 'D', 'S' };
        uint values[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
        for (uint i = 0; i != 4; i++)
        {
            for (uint j = 0; j != 13; j++)
            {
                cards.push_back(card(suits[i], values[j]));
            }
        }
    }
    void shuffle(void)
    {
        uint i = cards.size(), random_index;
        card shuffled_card;
        while (i > 0)
        {
            random_index = rand() % (i + 1);
            shuffled_card = cards[random_index];
            cards[random_index] = cards[i];
            cards[i] = shuffled_card;
            i--;
        }
    }
};

 void player::draw(deck& target_deck, uint number)
 {
      // Draw cards from the top of the 
      // target deck.
 }
#包括
#包括
#包括
typedef无符号整数单元;
舱面;
职业选手
{
私人:
std::字符串名;
集成电路芯片;
病媒手;
公众:
播放器(std::string set_name,uint set_chips){name=set_name;chips=set_chips;}
虚线绘制(甲板和目标甲板,uint编号);//在外部定义它。
};
甲板
{
私人:
向量卡;
公众:
朋友无效提款(甲板和目标甲板,uint编号);
void初始化(void)
{
字符匹配[]={'H','C','D','S'};
uint值[]={2,3,4,5,6,7,8,9,10,11,12,13,14};
对于(uint i=0;i!=4;i++)
{
对于(uint j=0;j!=13;j++)
{
卡片。推回(卡片(适合[i],值[j]);
}
}
}
无效洗牌(无效)
{
uint i=cards.size(),随机索引;
洗牌卡;
而(i>0)
{
随机指数=rand()%(i+1);
洗牌牌=牌[随机索引];
卡片[随机指数]=卡片[i];
卡片[i]=洗牌卡片;
我--;
}
}
};
无效玩家::抽牌(牌组和目标牌组,单位号码)
{
//从顶部抽牌
//目标甲板。
}

Greg的回答很好,我不认为您应该在这里使用友元函数。使用
initialize
函数而不是构造函数是怎么回事?友元成员函数应该工作:
cards.size()
将是一个
std::size\t
它可能是也可能不是一个
无符号int
Greg的答案可能是你应该如何实现它,但是FWIW,你的好友声明不起作用的原因是因为player::draw尚未声明。在这种情况下,你需要做一些前向声明,但这是可能的。Greg的回答很好,我不认为你应该使用友元函数