Order of Class Definitions in C++

被刻印的时光 ゝ 提交于 2019-12-12 10:48:57

问题


I've got a bit of a problem here. I'm trying to define several classes, of which some are Players and some are Pawns belonging to the players. Coming from Python, I'm used to being able to conveniently access a Pawn's owning Player through the Pawn, as well as accessing a Player's Pawns through the Player. Correct me if I'm wrong, but this seems impossible in C++.

I currently define Player first, and one of its data members m_Pawns is supposed to be a vector<Pawn>. I declare the data member, but I don't assign it any value. I also define a member function that is meant to assign a vector of pawns to m_Pawns, but I don't call it anywhere near the constructor. Since I'm not actually calling the constructor for Pawn in the constructor for Player, it seems I should be fine.

Here's my Player class. The Board class is defined beforehand, whereas the Pawn class is defined afterwards (the Pawn class contains pointers to an owner of the Player class, so switching it around doesn't really help).

class Player
{
public:
    Player(sf::Color color, const string& name);
    sf::Color GetColor();
    string GetName();
    void CreatePawns(Board& board, int which);
protected:
    vector<Pawn> m_Pawns;
    sf::Color m_Color;
    string m_Name;
};

Player::Player(sf::Color color, const string& name):
    m_Color(color),
    m_Name(name)
{}

sf::Color Player::GetColor()
{
    return m_Color;
}

string Player::GetName()
{
    return m_Name;
}

void Player::CreatePawns(Board& board, int which)
{
    switch(which)
    {
    case 1:
        for(int i = 0; i < 4; ++i)
        {
            m_Pawns.push_back(Pawn((*board).Cluster1[i], this*, m_Color));
        }
        break;
    case 2:
        for(int i = 0; i < 4; ++i)
        {
            m_Pawns.push_back(Pawn((*board).Cluster2[i], this*, m_Color));
        }
        break;
    case 3:
        for(int i = 0; i < 4; ++i)
        {
            m_Pawns.push_back(Pawn((*board).Cluster3[i], this*, m_Color));
        }
        break;
    default:
        cout << "Invalid player ID!\n\n";
        break;
    }
}

回答1:


If the class Player is coming first and class Pawn coming later then you can only declare pointer or reference to the later class (here Pawn). You cannot have objects of later class, e.g.

class Player {
  Pawn* p; // allowed
  Pawn& r; // allowed
  vector<Pawn*> p; // allowed
  vector<Pawn&> vr; // not allowed (reference are not copyable)
  vector<Pawn> o; // error !
};

class Pawn {};

There is no way you can overcome this situation, as in C++ for non-template class one need to show full definition to declare objects.

The only way out is to reformat your code or use pointer/reference (with forward declaration).




回答2:


The class Pawn still has to be defined so compiled can instantiate vector. You can get away with storing references or pointers to Pawn objects in your vector instead of values; vector for example. In that case forward declaration of class Pawn will be enough.




回答3:


You can switch it around, because you can forward declare Player, and then Pawn can have a pointer to it.

You can take a pointer to an incomplete type. You can't hold values of that type.




回答4:


You can do something like this:

class Pawn;

class Player {
}

class Pawn {
}


来源:https://stackoverflow.com/questions/6367995/order-of-class-definitions-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!