【问题标题】:How can I send multiple instances of an object into one function如何将对象的多个实例发送到一个函数中
【发布时间】:2013-01-20 04:59:18
【问题描述】:

我有一些看起来像这样的代码

class Split
{
public:
    Split(Hand *pcHand = NULL)
        : phand(pcHand), phandsplit(pcHand)
     {
     }

    int CardOne;
    int CardTwo;
    int CardThree;

    void getCardOne(Hand & phand)
    {
        CardOne = phand.SendCOneToSplit();
        std::cout << "Card One: " << CardOne << std::endl;
    }

    void getCardTwo(Hand & phandsplit)
    {
        CardTwo = phandsplit.SendCOneToSplit();
        std::cout << "Card Two: " << CardTwo << std::endl;
    }

    void getCardThree(Hand & phandsplitTwo)
    {
        CardThree = phandsplitTwo.SendCOneToSplit();
        std::cout << "Card Two: " << CardTwo << std::endl;
    }

private:
    Hand * phand;
    Hand * phandsplit;
};

我想让它成为一个函数,而不是添加另一个函数,它只对同一类的不同对象执行完全相同的操作。有没有办法做到这一点?如果是这样,谁能指出我正确的方向?

【问题讨论】:

  • 您熟悉 STL 容器吗?还是数组?
  • 一点点。我对编程比较陌生。我用过它们,但不是很大。
  • 我已经在下面回答了,但我对你的问题有些担心:你的函数接受一个名为 phand 的引用,并且该类有一个同名的指针,你没有使用.您是否故意在问题中包含这些成员变量?
  • 不,前段时间我把它们放在那里,当时我在乱搞,忘了把它们拿出来。

标签: c++ class object parameter-passing


【解决方案1】:

只需向函数传递一个附加参数,该参数告诉您要处理哪个类成员。

enum
{
    CardOne, CardTwo, CardThree, //so on....
}CardNumber;

void getCard(Hand & phandsplitTwo, CardNumber card)   
{
    if(card == CardOne)
       CardOne = phand.SendCOneToSplit();
    else if(card == CardTwo)
       CardTwo = phandsplit.SendCOneToSplit();
    else if(card == CardThree)
       CardThree = phandsplitTwo.SendCOneToSplit();
    //....
}

注意:
我不知道您为什么将您的方法命名为 getXXXXX,但它们实际上并没有返回任何内容。或许,名字应该是setXXXXXX??

【讨论】:

  • 什么样的参数可以做到这一点?我可以使用字符串吗?
  • @user1956980:更新了答案。
【解决方案2】:

好吧,既然你的变量是公开的,你总是可以只传递你想要操作的那个:

void getCard(Hand& hand, int& card)
{
    card = hand.SendCOneToSplit();
    std::cout << "Card: " << card << std::endl;
}

然后这样调用:

split.getCard(hand, split.CardOne);

当然,使用公共变量可能不是一个长期的解决方案,所以另一种选择是替换:

int CardOne;
int CardTwo;
int CardThree;

使用数组:

int cards[3];

然后只需传入你想要的索引:

void getCard(Hand& hand, int ndx)
{
    cards[ndx] = hand.SendCOneToSplit();
    std::cout << "Card: " << cards[ndx] << std::endl;
}

【讨论】:

  • 如果调用者传递了一个超出范围的索引会发生什么? 轰隆隆!
  • @Alok:那么您的输入无效。何时以及如何处理无效输入是一个完全不同的话题。
  • IMO 的一般准则是,您应该提供一个安全的接口,该接口不会将传递正确输入的全部责任委托给调用者。您的代码至少应该处理错误的输入。
  • @Alok:std::string 和 std::vector 等类不遵循“一般准则”;就像我说的,我们可以对此进行大量讨论。解决这个问题的一个更严格的解决方案是将您的答案与我的答案混合,将 CardNumber 转换为索引,但我也可以想到其他三个有效的解决方案,它们都不能帮助回答 OP 的问题。
  • 哦,让我试着解释一些更好的东西。目标是不使用三个卡片变量。实际上,我只需要一个,因为我从玩家手中抓起一张牌以在第二只手中重置它。这只是为了获取变量,以便可以将其发送出去。我最终只想为卡片使用一个变量,并使用不同的对象抓取一张卡片;但是。
【解决方案3】:

如果关心性能,如果有很多“卡片类型”;我会使用函数指针(即方法指针)。

void (Split::*pfGetTheCard)(Hand & phand);

// Dynamically assign it to one of those:
pfGetTheCard =  &Split::getCardTwo;

// And call it:
(cardobj.*pfGetTheCard)(); 
(pCardPtr->*pfGetTheCard)(); 

请注意,这可能不是合适的解决方案,因为这完全取决于您的设计、性能和维护问题。这只是我的想法!

【讨论】:

  • 性能不是什么大问题,所以我会试一试,看看效果如何。非常感谢! ;)
猜你喜欢
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 2013-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-29
相关资源
最近更新 更多