Ryan Sayles
Ryan Sayles

Reputation: 3441

C++ Enum Values

I'm trying to learn C++ by converting a few Java classes I made a while ago. They represent a playing card and a deck of cards. I'm using an enum for the values and suits as such:

enum Suits{SPADES, CLUBS, HEARTS, DIAMONDS};

enum Values{TWO, THREE, FOUR, FIVE, 
            SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE};

In both my Java and C++ Card class I have methods: getValue() and getSuit() which obviously return the value and suit respectively.

My Java DeckofCards class is pretty simple:

public class DeckofCards {

private Card card; 
private String value;
private String suit;
private List<Card> deck = new ArrayList<Card>();

//DeckofCards constructor
public DeckofCards(){
    for (Suits s : Suits.values()) {
        for(Values v : Values.values()){
            card = new Card(v,s);
            deck.add(card);
        }  
    }
}

//shuffles the deck
public void shuffleDeck(){
    Collections.shuffle(deck);
}

//prints the deck of cards
public void printDeck(){

    for(int i = 0; i<deck.size(); i++){
        card = deck.get(i);
        value = card.getValue().toString();
        suit = card.getSuits().toString();
        System.out.println(value + " of " + suit);
    }

}

//draws a card from the deck
public Card drawCard(){
    try{
        card = deck.get(0);
        deck.remove(0);
        //return card;
    }
    catch(IndexOutOfBoundsException e){
        System.err.println("Deck is empty");
        System.exit(0);
    }
    return card;
}

} 

My problem is implementing the printDeck() method in C++, specifically getting the string representation of the enum values. I know I can't simply do getValue().toString() So my idea after doing some research on the matter was to make two std::string[] that look the same as the two enums and then use the getValue() and getSuit() to generate an int (since that seems to be the behavior) and pass that into the array to get the string representation.

However I'm now thinking that it might be better to add two more methods in my Card class:

std::string getValue(int i) and likewise for suit

and use a case statement to return a string value based on the int so that other classes can easily get the string representation. This seems redundant though. Can anyone provide any suggestions on how to do this?

Upvotes: 2

Views: 3068

Answers (2)

Mr.C64
Mr.C64

Reputation: 43034

You can use new C++11 enum classes (i.e. scoped enums), and define a function that takes such an enum class as input parameter, and returns the corresponding string representation for the input enum value.

e.g.:

#include <assert.h>     // For assert()
#include <iostream>     // For console output
#include <string>       // For std::string

enum class Suits {
    SPADES, CLUBS, HEARTS, DIAMONDS
};

std::string toString(Suits s) {
    switch (s) {
    case Suits::SPADES:     return "Spades";
    case Suits::CLUBS:      return "Clubs";
    case Suits::HEARTS:     return "Hearts";
    case Suits::DIAMONDS:   return "Diamonds";
    default:
        assert(false);
        return "";
    }
}

int main() {
    std::cout << toString(Suits::CLUBS) << std::endl;
}

You can do a similar thing for the Values enum.

Upvotes: 2

dutt
dutt

Reputation: 8209

In C++ there's no metadata around enums, so if you want a string version you need to write a converter yourself.

I'd probably go with something like this, this doesn't compile but you get the rough picture.

enum Suit { ... }
enum Values { ... }

Class card {
public:
   static std::string getText(Suite s) { switch(s) case CLUBS: return "clubs"; ... }
   static std::string getText(Colour c) { switch(c) case ONE: return "one"; ... }

   card(Suite s, Colour c) : mSuite(s), mColour(c) {}
   std::string getText() const {
       stringstream ss;
       ss << getText(mColour) << " of " << getText(mSuits);
       return ss.str();
   }
};
ostream& operator<<(ostream& stream, const card& c) {
    stream << c.getText();
}

Upvotes: 1

Related Questions