Zizou
Zizou

Reputation: 67

Why can an enumeration inside class A (public) be accessed in class B using scope operator and class A name?

as you can see in the code, enum CardSuit is not static

I don't understand how Deck constructor can directly access MAX_SUITS in this line of code:

for (int suit = 0; suit < Card::MAX_SUITS; ++suit)

Shouldn't an object of class Card be needed for class Deck to access MAX_SUITS?

something like:

Card card1;
for (int suit = 0; suit < card1::MAX_SUITS; ++suit)

If I declare int x; in Class Card and say Card::x inside definition of class Deck, then I get an error saying "improper use of non-static member". I was expecting to get the same error for usage of Card::MAX_SUITS too, but that does not seem to be the case, it works fine.

Here is the relevant part of the program:

class Card
{
public:
    enum CardSuit
    {
        SUIT_CLUB,
        SUIT_DIAMOND,
        SUIT_HEART,
        SUIT_SPADE,
        MAX_SUITS
    };

    enum CardRank
    {
        RANK_2,
        RANK_3,
        RANK_4,
        RANK_5,
        RANK_6,
        RANK_7,
        RANK_8,
        RANK_9,
        RANK_10,
        RANK_JACK,
        RANK_QUEEN,
        RANK_KING,
        RANK_ACE,
        MAX_RANKS
    };

private:
    CardRank m_rank;
    CardSuit m_suit;

public:

    Card(CardRank rank=MAX_RANKS, CardSuit suit=MAX_SUITS) :
        m_rank(rank), m_suit(suit)
    {

    }

    int getCardValue() const
    {
        switch (m_rank)
        {
        case RANK_2:        return 2;
        case RANK_3:        return 3;
        case RANK_4:        return 4;
        case RANK_5:        return 5;
        case RANK_6:        return 6;
        case RANK_7:        return 7;
        case RANK_8:        return 8;
        case RANK_9:        return 9;
        case RANK_10:       return 10;
        case RANK_JACK:     return 10;
        case RANK_QUEEN:    return 10;
        case RANK_KING:     return 10;
        case RANK_ACE:      return 11;
        }

        return 0;
    }
};

class Deck
{
private:
    std::array<Card, 52> m_deck;

public:
    Deck()
    {
        int card = 0;
        for (int suit = 0; suit < Card::MAX_SUITS; ++suit)
            for (int rank = 0; rank < Card::MAX_RANKS; ++rank)
            {
                m_deck[card] = Card(static_cast<Card::CardRank>(rank), static_cast<Card::CardSuit>(suit));
                ++card;
            }
    }

};

Upvotes: 3

Views: 63

Answers (3)

Tzalumen
Tzalumen

Reputation: 660

Enums are types, not member variables. Therefore, if they are public:, they can be accessed; the scope operator treats the class as an additional qualifier.

Upvotes: 7

templatetypedef
templatetypedef

Reputation: 372764

Good question!

In C++, if you declare a (non-static) variable inside of a class, C++ interprets that declaration to mean “each instance of this class has a data member with this name and type.” On the other hand, if you declare a type inside of a class - whether that’s an enumerated type, a struct, or a class - C++ interprets it to mean “this a type just like any other type, except that it’s scoped inside the containing class.” That is, a nested type declaration functions as though you’d declared a regular type, except that its name contains the enclosing class’s name as a prefix. As a result, there’s no need to have an object of the enclosing type available to access the enumerated type or the values of that enumerated type.

Upvotes: 5

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122228

The enums are types not data, hence no, you do not need an object to access them.

Consider this completely different albeit similar example:

struct foo {
   struct bar {};
};

int main() {
    foo::bar foobar;
}

No problem here. You do not need an instance to access bar.

Upvotes: 5

Related Questions