首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类和头文件之间的关系

类和头文件之间的关系
EN

Stack Overflow用户
提问于 2022-04-02 19:12:30
回答 2查看 266关注 0票数 1

我正在学习如何在C++中使用类。这是我的文件结构。

main.cpp (sueca.cpp)

代码语言:javascript
复制
#include "Card.h"
#include "Deck.h"
#include "Player.h"
#include "Turn.h"
#include "Game.h"

int main ()
{
    std::cout << "\t\t\t.:: Sueca Game ::." << std::endl;

    Game sueca;
    //sueca.startGame();
    
    return 0;
}

卡:

代码语言:javascript
复制
#ifndef CARD_H
#define CARD_H

#include <iostream>             // std::cout
#include <string>               // std::string

class Card {
    public:
        Card();
        Card(int&, int&);
        ~Card();
        int getSuit() const;
        int getRank() const;
        int getPoints() const;
        void printCard () const;
        void setSuit(int&); 
        void setRank(int&);
        void setCard(int&, int&);

    private:
        int suit;
        int rank;
};

#endif

Card.cpp

代码语言:javascript
复制
#include "Card.h"

Card::Card ()
{
    suit = -1;
    rank = -1;
}

Card::Card (int &isuit, int &irank)
{
    suit = isuit;
    rank = irank;
}

Card::~Card ()
{

}

int Card::getSuit () const
{
    return suit;
}

int Card::getRank () const
{
    return rank;
}

void Card::setSuit (int &isuit) 
{
    suit = isuit;
    return;
}

void Card::setRank (int &irank) 
{
    rank = irank;
    return;
}

void Card::setCard (int &isuit, int &irank)
{
    suit = isuit;
    rank = irank;
}


int Card::getPoints () const
{
    if (rank <= 4)
        return 0;
    else if (rank <= 7)
        return rank-3;
    else
        return rank+2;
}

void Card::printCard () const
{
    std::string naipe, nome;
    switch (suit) 
    {
        case 0: 
            naipe = "HEARTS";
            break;
        case 1:
            naipe = "DIAMONDS";
            break;
        case 2:
            naipe = "CLUBS";
            break;
        case 3:
            naipe = "SPADES";
            break;
    }
    switch (rank)
    {
        case 0: 
            nome = "TWO";
            break;
        case 1:
            nome = "THREE";
            break;
        case 2:
            nome = "FOUR";
            break;
        case 3:
            nome = "FIVE";
            break;
        case 4:
            nome = "SIX";
            break;
        case 5:
            nome = "QUEEN";
            break;
        case 6:
            nome = "JACK";
            break;
        case 7:
            nome = "KING";
            break;
        case 8:
            nome = "SEVEN";
            break;
        case 9:
            nome = "ACE";
            break;
    }

    std::cout << nome << " of " << naipe;
    return;
}

德克.h:

代码语言:javascript
复制
#ifndef DECK_H
#define DECK_H

#include <iostream>             // std::cout
#include <algorithm>            // std::shuffle
#include <array>                // std::array
#include <string>               // std::string
#include <random>               // std::default_random_engine
#include <chrono>               // std::chrono::system_clock

#include "Card.h"

class Deck : public Card{
    public:
        Deck();
        ~Deck();
        void shuffleDeck(int&); 
        void printDeck();   

    private:
        std::array<Card,40> element;         
};

#endif

Deck.cpp:

代码语言:javascript
复制
#include "Deck.h"

Deck::Deck ()
{
    auto i = 0;
    for (auto s = 0; s < 4; ++s)
    {
        for (auto r = 0; r < 10; ++r)
        {
            element[i].setCard(s, r);
            ++i;
        }
    }
}

void Deck::shuffleDeck (int &times)
{
    for (auto i = 0; i < times; ++i)
    {
        unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
        std::shuffle(element.begin(), element.end(), std::default_random_engine(seed));
    }
    return;
}

void Deck::printDeck ()
{
    for (auto c = 0; c < element.size(); ++c)
    {
        std::cout << "card\t(" << c << ")\t";
        element[c].printCard();
    }
    return;
}

Player.h:

代码语言:javascript
复制
#ifndef PLAYER_H
#define PLAYER_H

#include <iostream>             // std::cout
#include <string>               // std::string
#include <array>                // std::array

#include "Card.h"

class Player : public Card {
    public:
        Player();
        Player(int&, std::string&);
        ~Player();
        int getID() const;
        std::string getName() const;
        int getPoints() const;
        int printHand() const;
        void setID(int&);
        void setName(std::string&);
        void setPoints(int&);

    private:
        int id;
        std::string name;
        int points = 0;
        std::array<Card,10> hand;         
};

#endif

Player.cpp

代码语言:javascript
复制
#include "Player.h"

Player::Player ()
{
    id = -1;
    points = 0;
}

Player::Player (int &iid, std::string &iname)
{
    id = iid;
    name = iname;
    points = 0;
}

Player::~Player ()
{
    
}

int Player::getID () const
{
    return id;
}

std::string getName () const
{
    return name;
}

int Player::getPoints () const
{
    return points;
}

int Player::printHand () const
{
    if (hand.size() == 0)
    {
        std::cout << "\t\t\tERROR: Player " << name << " has no cards (" << id << ")" << std::endl;
        return -1;
    }

    std::cout << "(" << id << ") " << name << "'s cards:" << std::endl;
    for (auto i = 0; i < 10; ++i)
        hand[i].printCard();

    return 0;
}

void Player::setID(int &iid)
{
    id = iid;
    return;
}

void Player::setName(std::string &iname)
{
    name = iname;
    return;
}

void Player::setPoints(int &ipoints)
{
    points = ipoints;
    return;
}

Turn.h:

代码语言:javascript
复制
#ifndef TURN_H
#define TURN_H

#include <iostream>             // std::cout
#include <array>                // std::array

#include "Player.h"
#include "Card.h"

// NOTE: I'd like to access the variable "trump" from the class Game, making it the parent of this class (one game has many turns)

class Turn {
    public:
        Turn();
        Turn(int&, std::array<Player,4>&);
        ~Turn();
        int getID() const;
        int playTurn();
        int getTurnWinner();
        
    private:
        int id;
        //int trump; --> use the trump variable from the parent Game instead
        std::array<Player,4> gamer;
        std::array<Card,4> move;    
};

#endif

Turn.cpp:

代码语言:javascript
复制
#include "Turn.h"

Turn::Turn ()
{
    id = -1;
}

Turn::Turn (int &roundNO, std::array<Player,4> &players)
{
    id = roundNO;
    gamer = players;
}

int Turn::getID () const
{
    return id;
}

int Turn::playTurn ()
{   
    for (auto p = 0; p < 4; ++p)
    {
        std::cout << "\t(" << p << ") " << gamer[p].getName() << "'s turn!" << std::endl;

        if (gamer[p].printHand() == -1)
            return -1;
        
        std::cout << "Pick the number of the card you want to play: ";

        int playcard;
        std::cin >> playcard;

        while (playcard > 10)
        {
            std::cout << "Invalid selection!\nPick the number of the card you want to play: ";
            std::cin >> playcard;
        }
        
        //move[p] = gamer[p].hand[playcard];
    }    

    return 0;
}

int Turn::getTurnWinner ()
{
    Card max, maxtrunfo;
    int winner, winnertrunfo, points = 0;
    bool trunfo = false;

    if (move.size() < 4)
    {   
        std::cout << "\t\t\tERROR: Round " << id << " has" << move.size() << " cards." << std::endl;
        return -1;
    }
    if (gamer.size() < 4)
    {   
        std::cout << "\t\t\tERROR: Round " << id << " has" << gamer.size() << " cards." << std::endl;
        return -2;
    }

    for (auto i = 0; i < 4; ++i)
    {
        if (move[i].getRank() > max.getRank())
        {
            max = move[i];
            winner = i;
        }
            
        if ((move[i].getSuit() == trump) && (move[i].getRank() > maxtrunfo.getRank()))                                                ///VER ISTO
        {
            maxtrunfo = move[i];
            trunfo = true;
            winnertrunfo = i;
        }

        points += move[i].getPoints();
    }

    if (trunfo)
    {
        std::cout << "\t(" << winnertrunfo << ") " << gamer[winnertrunfo].getName() << " wins!" << std::endl;
        //gamer[winnertrunfo].getPoints() = points;
    }
    else
    {
        std::cout << "\t(" << winner << ") " << gamer[winner].getName() << " wins!" << std::endl;
        //gamer[winner].getPoints() = points;
    }

    return 0;
}

加梅赫:

代码语言:javascript
复制
#ifndef GAME_H
#define GAME_H

#include <iostream>             // std::cout
#include <algorithm>            // std::shuffle
#include <array>                // std::array
#include <string>               // std::string
#include <random>               // std::default_random_engine
#include <chrono>               // std::chrono::system_clock

#include "Turn.h"
#include "Player.h"

class Game {
    public:
        //Game();
        //~Game();
        int startGame();
        int setTrump();

    private: 
        int trunfo;
        int duration;
        Deck gamedeck;
        std::array<Turn,10> round;
        std::array<Player,4> gamer;
};

#endif

Game.cpp

代码语言:javascript
复制
#include "Game.h"

/*Game::Game ()
{
    trunfo = -1;
    duration = 0;
}

Game::~Game ()
{

}*/

int Game::setTrump ()
{
    unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
    std::default_random_engine generator(seed);
    std::uniform_int_distribution<int> gamer(0,3);
    int player = gamer(generator);
    
    return player;
}

int Game::startGame ()
{
    int shuffle = 1;

    std::cout << "How many times do you want to shuffle the deck? ";
    std::cin >> shuffle;

    while (shuffle < 1)
    {
        std::cout << "Please insert an integer bigger than 0.\nHow many times do you want to shuffle the deck? ";
        std::cin >> shuffle;
    }

    gamedeck.printDeck();
    gamedeck.shuffleDeck(shuffle);

    std::cout << "Deck shuffled " << shuffle << " times!" << std::endl;
    std::cout << "\t * The player pairings will be (1 & 3) and (2 & 4). Let's proceed to name each player." << std::endl;

    std::string playername;
    for (auto i = 0; i < 4; ++i)
    {
        std::cout << "Type the name of Player " << i+1 << ": ";
        std::cin >> playername;

        while (playername.size() == 0)
        {
            std::cout << "Please insert a readable name.\nType the name of Player " << i+1 << ": ";
            std::cin >> playername;
        }

        gamer[i].id = i;
        gamer[i].name = playername;
        
        for (auto c = 0; c < 10; c++)
            gamer[i].hand[c] = gamedeck.element[c+i*10];                                                                        /// APRENDER A PASSAR O ENDEREÇO DA CARTA
    }

    // Set trump card & suit
    int trump_player, trump_card;
    trump_player = setTrump();

    std::cout << "The trump card is (" << trump_player << ") "<< gamer[trump_player].name << "'s ";
    gamer[trump_player].hand[0].print_card();
    trunfo = gamer[trump_player].hand[0].suit;

    return 0;
}

终端错误:

代码语言:javascript
复制
g++ sueca.cpp -o sueca
/usr/bin/ld: /tmp/ccmCL0jl.o: in function `std::array<Turn, 10ul>::array()':
sueca.cpp:(.text._ZNSt5arrayI4TurnLm10EEC2Ev[_ZNSt5arrayI4TurnLm10EEC5Ev]+0x27): undefined reference to `Turn::Turn()'
/usr/bin/ld: sueca.cpp:(.text._ZNSt5arrayI4TurnLm10EEC2Ev[_ZNSt5arrayI4TurnLm10EEC5Ev]+0x7d): undefined reference to `Turn::~Turn()'
/usr/bin/ld: /tmp/ccmCL0jl.o: in function `std::array<Turn, 10ul>::~array()':
sueca.cpp:(.text._ZNSt5arrayI4TurnLm10EED2Ev[_ZNSt5arrayI4TurnLm10EED5Ev]+0x39): undefined reference to `Turn::~Turn()'
/usr/bin/ld: /tmp/ccmCL0jl.o: in function `std::array<Player, 4ul>::array()':
sueca.cpp:(.text._ZNSt5arrayI6PlayerLm4EEC2Ev[_ZNSt5arrayI6PlayerLm4EEC5Ev]+0x27): undefined reference to `Player::Player()'
/usr/bin/ld: sueca.cpp:(.text._ZNSt5arrayI6PlayerLm4EEC2Ev[_ZNSt5arrayI6PlayerLm4EEC5Ev]+0x76): undefined reference to `Player::~Player()'
/usr/bin/ld: /tmp/ccmCL0jl.o: in function `std::array<Player, 4ul>::~array()':
sueca.cpp:(.text._ZNSt5arrayI6PlayerLm4EED2Ev[_ZNSt5arrayI6PlayerLm4EED5Ev]+0x39): undefined reference to `Player::~Player()'
/usr/bin/ld: /tmp/ccmCL0jl.o: in function `Game::Game()':
sueca.cpp:(.text._ZN4GameC2Ev[_ZN4GameC5Ev]+0x1d): undefined reference to `Deck::Deck()'
/usr/bin/ld: sueca.cpp:(.text._ZN4GameC2Ev[_ZN4GameC5Ev]+0x75): undefined reference to `Deck::~Deck()'
/usr/bin/ld: /tmp/ccmCL0jl.o: in function `Game::~Game()':
sueca.cpp:(.text._ZN4GameD2Ev[_ZN4GameD5Ev]+0x40): undefined reference to `Deck::~Deck()'
collect2: error: ld returned 1 exit status

另外,我知道这些都是我读过的“C++之旅”的基本内容,但是它并没有详细介绍一些事情是如何完成的,所以我浏览网页,寻找解决代码中出现的问题的方法。尝试用一些以前的C知识自学C++。如果你能给我推荐一些进步的方法,我会很感激(也许我应该再买一本书?)。这个程序是我尝试从我的国家编码一个流行的纸牌游戏。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-04-02 21:16:22

你可能需要在你的书后退一点,但我会解释一点。

包含(.h)文件通常是存在的,这样就可以有10个使用声明类的.cpp文件。这就是你放Foo {.类东西的地方。那么,任何想要使用Foo的人都可以包含.h文件。

.cpp文件是实现类的地方。我想你明白这一点。

编译时,可以编译每个..cpp,然后将它们链接到一起。或者你可以这么做:

代码语言:javascript
复制
g++ --std=c++17 A.cpp B.cpp C.cpp -o MyProgram

这将对MyProgram进行编程(您可以任意命名它),并包含这三个.cpp文件中的所有代码。

当然,这可能会比这复杂得多。但是,如果您执行的g++行与我展示的类似,列出了所有的.cpp文件,那么只要您已经实现了您定义的所有代码,它就应该构建。

票数 1
EN

Stack Overflow用户

发布于 2022-04-03 02:53:27

在过去的c++时代,你必须定义.cpp和.h。在现代c++中,这不再是一个严格的要求。即使您有静态的,c++也有内联的静态,可以在标头中初始化静态。

我建议坚持17或以上,并保持每一个在各自的标题。

要使用.cpp、.cc或.c的地方是,如果您需要隐藏一个实现细节,但需要这样做,那么您必须记住在您的项目中包含.cc,例如使用.cc中的命名空间保存或包含第三方库。

另外,知道如何制作库和链接,dll也很好,但是这就变成了更多的杂务,可以用头来完成。但不是说标题是银弹,静态库dll也不是。他们更喜欢不同口味的东西,你可以释放。你还拥有ipc,比如共享内存和网络。但要坚持亲吻(保持简单愚蠢),并在必要时进行优化。

此外,如果您定义方法而没有实现,您将得到未定义的引用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71720495

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档