1

I write two override operators(<< for Suit and << for Card) in my code and it seems it does not work sometimes. I tried to call operator for Suit twice in the override operator << for Card. The second did not work, why?

class Card{ 
public:
    enum Suit{CLUBS, SPADES, HEARTS, DIAMOND};
    Card(int v, Suit s): value(v), suit(s){};
    int getValue()const{return value;}
    Suit getSuit()const{return suit;}
private:
    int value;
    Suit suit;
};

ostream& operator<< (ostream& out, Card::Suit& s){
    switch (s) {
        case 0:
            out << "CLUBS";
            break;
        case 1:
            out << "SPADES";
            break;
        case 2:
            out << "HEARTS";
            break;
        default:
            out << "DIAMOND";
            break;
    }
    return out;
}

ostream& operator<< (ostream& out, Card& c){
    Card:: Suit s = c.getSuit();
    out << s << endl;  //here it output what I want: SPADES
    out << "Card with Suit " << c.getSuit() << " Value " << c.getValue() << endl;
    return out; //here the c.getSuit() output 1 instead of SPADES, why?()
}

int main(){
    Card* c = new Card(1, Card::SPADES);
    cout << *c;
    return 1;
}
ivory
  • 243
  • 4
  • 16
  • Have a look at this question, I think it might help you: http://stackoverflow.com/questions/12802536/c-multiple-definitions-of-operator?rq=1 – Samuel O'Malley Oct 31 '13 at 04:12
  • @SamuelO'Malley Thanks for your response but I think they are not the same problem. I defined operator<< for different parameters and no error message showed. I am just confused about the result I have got. – ivory Oct 31 '13 at 04:16

1 Answers1

1

Try changing suit to an enum class - then it will be strongly typed and not cast to int.

...
enum class Suit {CLUBS,SPADES,HEARTS,DIAMONDS};
...

ostream& operator<<(ostream& os, Card::Suit& s) {
  switch (s) {
    case Card::Suit::CLUBS:
      os << "Clubs";
      break;
...

and then in your other code, cout << c.getSuit() << endl won't implicitly cast to an int and output the number.

Charlie
  • 1,487
  • 10
  • 9
  • you mean add this enum class before Card class. It can't compile, error: expected identifier or '{' enum class Suit {CLUBS,SPADES,HEARTS,DIAMONDS}; – ivory Oct 31 '13 at 04:30
  • by the way, when I use other compiler, it can compile now, but still the same result. – ivory Oct 31 '13 at 04:41
  • Sorry... didn't mean to pull it out of Card, just meant to use an enum class instead of an enum. Put `class` between `enum` and `suit`. http://www.cprogramming.com/c++11/c++11-nullptr-strongly-typed-enum-class.html – Charlie Oct 31 '13 at 04:50
  • Sorry, but still the same result. – ivory Oct 31 '13 at 05:07
  • Hmm... I just tested it on g++ 4.8.1 and it worked as expected. Then again, it works as expected with plain enum as well. – Charlie Oct 31 '13 at 05:37
  • @ivory The enum class is introduce by C++11. May be you need this command `g++ std=c++11 your.cpp`. – BlackMamba Oct 31 '13 at 07:59