v.pashaliuk
v.pashaliuk

Reputation: 37

clang: error: linker command failed with exit code 1 (use -v to see invocation) in C++ code

In the following code, in void Player::chooseDiscard I'm trying to assign the discard value of class Card to discardList array of the same class, but compiler recognizes it like undefined reference to 'Player::discardList'. How could I prevent this error?

class Player
{
public:
  Player();
  virtual void chooseDiscard(int);
  void replenish( );
  vector<Card>allCards;
  friend ostream& operator<<(ostream& os, Card hand);
  int selfIndex;      //index within player vector, starting with 0 for the human
  vector<Card>hand;   //holds 7 cards
protected:
  int takeFrom;       //player supplying new Car
  Card discard;       //card being discarded
  int discardIndex;   //position within hand of card being discarded
  static Card discardList[];
};
void Player::chooseDiscard(int number)
{
  discard = hand[number-97];
  discardIndex = number-97;
  discardList[selfIndex] = discard;
}

Upvotes: 1

Views: 578

Answers (1)

Schotmans
Schotmans

Reputation: 86

Well, you declared discardList as a static data member of the class Player, however by doing this you are not defining it.

The C++ ISO Standard says the following about this:

The declaration of a static data member in its class definition is not a definition and may be of an incomplete type other than cv-qualified void. The definition for a static data member shall appear in a namespace scope enclosing the member’s class definition. In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the :: operator.

So the compiler (actually it's the linker that complains) is right in reporting an undefined reference, because discardList was never defined.

What you should do, is define discardList out-of-line and in scope of the class Player, something like:

Card Player::discardList[] = {/* PUT SOME Card objects IN HERE*/};

Using a C-array can be quite restrictive as it has a fixed size, however it also might be very efficient if you know that discardList will never grow or shrink. Otherwise an std::vector is a better alternative.

Upvotes: 1

Related Questions