为什么可以使用范围运算符和A类名称在B类中访问A类(公共)中的枚举?

时间:2019-04-02 18:35:24

标签: c++

如您在代码中所见,enum CardSuit不是static

我不明白Deck的构造函数如何在此代码行中直接访问MAX_SUITS

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

Card不需要访问Deck的类MAX_SUITS的对象吗?

类似:

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

如果我在类卡中声明了int x;,并在类Card::x的定义内说了Deck,那么我会收到一条错误消息:“非静态成员的不当使用”。我原本也希望在使用Card::MAX_SUITS时也会遇到相同的错误,但事实并非如此,它工作正常。

这是程序的相关部分:

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;
            }
    }

};

3 个答案:

答案 0 :(得分:7)

枚举是类型,而不是成员变量。因此,如果它们是public:,则可以访问它们;范围运算符将类视为其他限定符

答案 1 :(得分:5)

枚举不是数据类型,因此不,您不需要对象即可访问它们。

考虑这个完全不同的示例,尽管如此:

struct foo {
   struct bar {};
};

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

这里没问题。您不需要实例即可访问bar

答案 2 :(得分:5)

好问题!

在C ++中,如果您在类内部声明一个(非静态)变量,则C ++将该声明解释为意味着“该类的每个实例都具有具有此名称和类型的数据成员。”另一方面,如果您在类内部声明了一种类型-无论是枚举类型,结构还是类-C ++都将其解释为“与其他类型一样,除了在包含类之内作用域之外,还像其他任何类型。”也就是说,嵌套类型声明的功能就好像您声明了常规类型一样,只不过其名称包含封闭类的名称作为前缀。因此,不需要使用封闭类型的对象来访问枚举类型或该枚举类型的值。