2

I'm new to C++ and trying to make a Blackjack simulator. The Player is a class that stores cards dealt from the deck; class Card contains a suit value and a face value. I keep getting error message "Control may reach end of non-void function" for Card Player::getCard( int index ) const, what did I do wrong? Also can someone check if there is any logic flaws in my code since I can't run it and check because of the error message?

#include "Player.h"
#include "Game.h"
#include "Card.h"
using namespace std;

Player::Player( )
{
    // The Player has no Cards in his hand
    myNumberOfCards = 0;
}

std::ostream& operator <<( std::ostream& outs, const Player & p )
{
    // print out all the actual cards in the array myCards
    for (int i = 0; i < p.cardCount(); i++)
    {
        outs << p.myCards[i] << endl;
    }
    return( outs );
}

void Player::acceptCard(Card c)
{
    // as long as there is space in the array myCards, place Card c into myCards
    //        if there is not enough space for another card, throw an exception
    try
    {
        for (; myNumberOfCards < MAXCARDS; myNumberOfCards++)
            myCards[ myNumberOfCards ] = c;
        if (myNumberOfCards > MAXCARDS)
            throw myNumberOfCards;
    }
    catch (int e)
    {
        std::logic_error( "more than maximum of cards possible" ); // Since the player must be busted if he has more than 11 cards, how should I set the outcome to playerbusted if I have a bool in the game class?
    }
}

Card Player::getCard( int index ) const
{
    // return the requested card
    // if the index is bad, throw an exception
    try
    {
        while ( index > 0 && index < myNumberOfCards )
            return ( myCards[ index ] );
        if (index < 0 || index > myNumberOfCards)
            throw index;
    }
    catch (int e)
    {
        std::logic_error( "bad index" ); // why there's an error?
    }
}

int Player:: cardCount() const
{
    //  return the number of cards stored in my array
    return myNumberOfCards;
}

int  Player::handcount( ) const
{
    // total up the points in this player's hand
    // Ace's might be worth 1 or 11
    Player p;
    int total = 0;
    bool hasAce = false;
    for (int i = 0; i < myNumberOfCards; i++)
    {
        total += myCards[i].count();
        if (myCards[i].getFace() == ACE)
            hasAce = true;
    }
    if (total < 11 && hasAce == true)
        total += 10;
    return( total );
}


bool Player::hasBlackJack( ) const
{
    bool result = false;
    if (myNumberOfCards == 2 && handcount() == 21)
    {
        result = true;
    }
    return( result );
}
553535782
  • 23
  • 4
  • 1
    _"... since I can't run it and check because of the error message?"_ What about fixing that error first? – πάντα ῥεῖ Mar 08 '16 at 09:16
  • 1
    The loop in `getCard` is equivalent to a conditional; it will execute once or not at all. A simpler variant is `if (index < 0 || index >= myNumberOfCards) throw std::logic_error("bad index"); else return myCards[index];`. – molbdnilo Mar 08 '16 at 09:23

1 Answers1

2
// vvvv must return a Card
   Card Player::getCard( int index ) const
{
    try
    {
        // ...
            throw index;
    }
    catch (int e)
    {
        std::logic_error( "bad index" ); // this doesn't throw, so will continue past
    }
    // ends up here, doesn't return
}

You don't throw a std::logic_error, just construct one in place and then do nothing with it.

In the event of an error that hits throw index, you end up hitting the bottom of the function without returning anything, which is Undefined Behaviour (very bad, anything can happen).

Probably you meant to throw std::logic_error("bad index");? This would cause you to exit the function with an exception, rather than normal returning, so wouldn't cause the problem.

It would just be simpler to get rid of the try/catch in getCard, and replace

throw index;

with

throw std::logic_error("bad index");

since the end result to the caller is the same. And ditch the while, since it isn't really a loop, just a check. Here's the simplified version:

Card Player::getCard( int index ) const
{
    // return the requested card
    // if the index is bad, throw an exception
    if ( index > 0 && index < myNumberOfCards )
        return ( myCards[ index ] );
    else
        throw std::logic_error("bad index");
}

You make the same error in acceptCard, but since it returns void, you don't see the error message: "falling off the bottom" of a void function is allowed, it acts like the last line is just return;.


Also, please reconsider your use of bad practices using namespace std; and endl.

Community
  • 1
  • 1
BoBTFish
  • 19,167
  • 3
  • 49
  • 76
  • My teacher didn't really talk about this in class... why is "using namespace std;" and "endl" worse than "std::cin/cout" and "\n"? – 553535782 Mar 08 '16 at 09:40
  • @553535782 Note that both of those are links to descriptions that would be too big to fit into the comments. The first an SO question with good answers, the second a blog post I wrote up because I didn't find a good explanation (so bear in mind, no one has been able to vote it up or down, since it isn't on SO). – BoBTFish Mar 08 '16 at 09:50