2012-10-29 14 views
5

Obecnie próbuję skompilować i połączyć moje pliki C++ na terminalu linux. Polecenie, które wykonuję to:Niezdefiniowane odniesienie do "funkcji" - problem z linkerem?

Polecenie wydaje się kompilować wszystko idealnie, ale gdy spróbuje połączyć rzeczy, otrzymam 2 błędy.

undefined reference to 'gamePlay::deal(std::vector<card, std::allocator<card> >, std::vector<player, std::alloator<player> >)' 

undefined reference to 'gamePlay::score(player)' 

Poniżej znajduje się mój plik gamePlay.CPP. Naprawdę jestem zagubiony i każda pomoc będzie doceniona!

#include "gamePlay.h" 
#include <cstdlib> 
#include <sstream> 

int gamePlay::compareCenter(int leadplayer){ 
int highest = center[leadplayer].getCardNum(); 
if(center[leadplayer].getCardNum() == 1) 
    highest = center[leadplayer].getCardNum() + 13; 
int suit = center[leadplayer].getSuit(); 
int player = leadplayer; 

for(int i = leadplayer+1; i < leadplayer+4; i++) 
{ 
    if((suit != 1) && (center[i%4].getSuit() == 1)) 
    { 
     player = i%4; 
     suit = 1; 
     highest = center[i%4].getCardNum(); 
    } 
    else if(suit == center[i%4].getSuit()) 
     if(center[i].getCardNum() == 1){ 
      player = i % 4; 
      highest = center[i].getCardNum() + 13; 
     } 
     if(highest < center[i%4].getCardNum()) 
     { 
      player = i%4; 
      highest = center[i%4].getCardNum(); 
     } 

} 
players.at(player).setTricksTaken(players.at(player).getTricksTaken()+1); 
return player; 
} 

vector <card> createDeck() { 
//Create the Deck and create each suit by calling define cards. 
vector <card> deck; 
for(int i = 1; i <= 4; i++){ 
    for(int j = 1; j <= 13; j++){ 
     card newCard (i,j); 
     deck.push_back(newCard); 
    } 
} 
random_shuffle (deck.begin(), deck.end()); 
return deck; 
} 

void gamePlay::deal(vector <card> &deck, vector <player> players){ 
for(int j = 0; j<4; j++){ 
    for(int i = 0; i<13; i++){ 
    players.at(j).addCard(deck.at(0)); 
    deck.erase(deck.begin()); 
    } 
} 
} 

bool containSuit(card lead, player players){ 
bool suit = false; 
for(int i = 0; i < players.getHand().size(); i++){ 
    if(lead.getSuit() == players.getHand().at(i).getSuit()) 
     suit = true; 
} 
return suit; 
} 

bool gamePlay::onlySpade(player play){ 
for(int i = 0; i<play.getHand().size(); i++){ 
    if(play.getHand().at(i).getSuit()!=1) 
    return false; 
} 
return true; 
} 

int gamePlay::handCheck(int xevent, int yevent, vector <player> players, int  trickStart){ 
     for(int i = 1; i < 14; i++){ 
      if(xevent<(i*6) && yevent>17 && yevent<23 &&  players.at(0).getHand().at(i-1).getSuit() != 0 && players.at(0).getHand().at(i- 1).getCardNum() != 0){ 
       card playedCard = players.at(0).getHand().at(i-1); 
       //first check to find card on display 
       //check to see if leading or not 
       //if leading use spadesBroken function 
       //if not leading use contains suit function 
       if(trickStart==0 && !getSpadesBroken()){ 
        if(onlySpade(players.at(0))) 
         return i; 
        else if(playedCard.getSuit() != 1) 
         return i; 
        else 
         return NULL; 
       } 
       if(trickStart == 0 && getSpadesBroken()) 
        return i; 
       if(trickStart > 0 && containSuit(center[trickStart],players.at(0))){ 
         if(playedCard.getSuit()==center[trickStart].getSuit()) 
         return i; 
       } 
       if(trickStart > 0 && !containSuit(center[trickStart],players.at(0))) 
        return i; 
       else 
        return NULL; 
      } 
     } 
} 

void gamePlay::displayHand(){ 
int offset = 0; 
    for(int i =0; i<players.at(0).getHand().size(); i++){ 
     monitor.displayCard(offset, 18,  players.at(0).getHand().at(i).getSuit(), players.at(0).getHand().at(i).getCardNum(), 0); 
     offset+=6; 
    } 
} 
void gamePlay::humanPlay(int trickStart){ 
    int xevent, yevent; 
    int key = monitor.captureInput(); 
    for(;;){ 
     mvprintw(8,26,"Please choose a card to play."); 
     // if a mouse event occurred 
     if (key == -1) { 
      xevent = monitor.getMouseEventX(); 
      yevent = monitor.getMouseEventY(); 
      int handCh = handCheck(xevent, yevent, players, trickStart); 
      if(handCh != NULL){ 
       card played = players.at(0).getHand().at(handCh-1); 
       players.at(0).getHand().at(handCh-1).setCardNum(0); 
       players.at(0).getHand().at(handCh-1).setSuit(0); 
       center[0]= played; 
       monitor.displayCard(34, 11, center[0].getSuit(), center[0].getCardNum(), 0); 
       displayHand(); 
       break; 
      } 
     } 
    } 
} 
void gamePlay::CPUplay(int trickStart, int CPU){ 
    bool goodCard = false; 
    card playedCard =players.at(CPU).getHand().at(0); 
    int i; 
    for(i = 0; i < players.at(CPU).getHand().size(); i++){ 
      playedCard = players.at(CPU).getHand().at(i); 
       //check to see if leading or not 
       //if leading use spadesBroken function 
       //if not leading use contains suit function 
       if(trickStart==CPU && !getSpadesBroken()){ 
        if(onlySpade(players.at(CPU))) 
         break; 
        if(playedCard.getSuit()!=1) 
         break; 
       } 
       if(trickStart == CPU && getSpadesBroken()) 
        break; 
       if(trickStart != CPU && containSuit(center[trickStart], players.at(CPU))){ 
         if(playedCard.getSuit()==center[trickStart].getSuit()) 
         break; 
       } 
       if(trickStart != CPU && !containSuit(center[trickStart], players.at(CPU))) 
        break; 
    } 
       players.at(CPU).getHand().at(i).setCardNum(0); 
       players.at(CPU).getHand().at(i).setSuit(0); 
       center[CPU]= playedCard; 
       if(CPU==1) 
       monitor.displayCard(29, 7, center[CPU].getSuit(), center[CPU].getCardNum(), 0); 
       if(CPU==2) 
       monitor.displayCard(39, 2, center[CPU].getSuit(), center[CPU].getCardNum(), 0); 
       if(CPU==3) 
       monitor.displayCard(49, 7, center[CPU].getSuit(), center[CPU].getCardNum(), 0); 
} 


void gamePlay::score(player play){ 

int trickOver = play.getBid()-play.getTricksTaken(); // Calculate the difference between bid and actually taken. 

//Bidding Double Nil (if gets it 200 points other wise -200 points) 
if(play.getDoubleNil()){ 
    if(play.getTricksTaken()==0) //player did get Double Nil successfully 
     play.setScore(play.getScore()+200); // add 200 points 
    else 
     play.setScore(play.getScore()-200); 
} 
if(play.getBid()==0){ //Bidding Nil (if gets it 100 points other wise -100 points) 
    if(play.getTricksTaken()==0) //player did get Nil successfully 
     play.setScore(play.getScore()+100); //add 100 points 
    else //player didnt get Nil 
     play.setScore(play.getScore()-100); //take away 100 points 
} 
if(trickOver>0){ //player bids more than number of tricks won 
    play.setScore((trickOver*-10)); //decrease score by 10 poitns for every overtrick 
} 
if(trickOver<0){ //player bids less then number of tricks won 
    play.setSandBag(play.getSandBag() + 1); //increase sandbag by 1 
    play.setScore((trickOver*(-1))+(10*(play.getBid()))); //increase 10 points per trick bid on and 1 point per trick over 
} 
if(play.getSandBag()>10){ //check for sandbagging 
    play.setScore(play.getScore()-100); 
} 
play.setBid(NULL); //reset players bid to NULL 
play.setDoubleNil(false); //Player has not yet bid double NILL. 
} 

void gamePlay::runGame(){ 

for(int i = 0; i<4; i++){ //Creates 4 players with hands included 
    player play; 
    players.push_back(play); 
} 

int count = 0; 
int handStart = 0; 
while(players.at(0).getScore()<500 || players.at(1).getScore()<500 || players.at(2).getScore()<500 || players.at(3).getScore()<500) 
{ 
    int xevent; 
    int yevent; 
    for(;;){ 
     mvprintw(3,2,"Click here to bid Double Nil or type out your bid now."); 
     int key = monitor.captureInput(); 
     monitor.drawBox(7, 4, 3, 2, 0); 
     monitor.drawBox(7, 4, 3, 2, 0); 
     if (key == -1) { 
      xevent = monitor.getMouseEventX(); 
      yevent = monitor.getMouseEventY(); 
      break; 
     } 
     if (key > 0){ 
     stringstream messageString; 
     messageString.str(""); 
     messageString << "Your bid is now: " << key; 
     monitor.bannerBottom(messageString.str()); 
     players.at(0).setBid(key); 
     break; 
     } 
    } 
    if((xevent>=7 && xevent<=10)&&(yevent>=4 && yevent <=6)){ 
     players.at(0).setDoubleNil(true); 
    } 

    vector <card> deck = createDeck(); 

    deal(deck, players); 
    displayHand(); 
    int trickStart = handStart; 
    int count = 0; 
    while(count<13){ 
    switch (trickStart) 
    { 
    case 0: humanPlay(trickStart); 
      CPUplay(trickStart,1); 
      CPUplay(trickStart,2); 
      CPUplay(trickStart,3); 
    case 1: CPUplay(trickStart,3); 
      humanPlay(trickStart); 
      CPUplay(trickStart,1); 
      CPUplay(trickStart,2); 
    case 2: CPUplay(trickStart,2); 
      CPUplay(trickStart,3); 
      humanPlay(trickStart); 
      CPUplay(trickStart,1); 
    case 3: CPUplay(trickStart,1); 
      CPUplay(trickStart,2); 
      CPUplay(trickStart,3); 
      humanPlay(trickStart); 
    } 
    trickStart = compareCenter(trickStart); 
    } 
    for(int n =0; n<4;n++) 
     score(players.at(n)); 

    handStart = (handStart +1) % 4; 
} 
} 

Również tutaj jest mój plik card.h także

using namespace std; 

class card { //Create cards for deck 
int cardSuit; 
int cardNum; 
public: 

    int getSuit() {return cardSuit;} 
    int getCardNum() {return cardNum;} 
    void setSuit(int a){ cardSuit = a;} 
    void setCardNum(int a){cardNum = a;} 
    card (int suit, int number){cardSuit = suit; cardNum = number;} 
    card (void){cardSuit = 0; cardNum= 0;} 
}; 
+4

Dziękujemy za zrozumienie różnicy między kompilacją a łączeniem. Napraw jednak wcięcie kodu. –

+1

Wydaje się, że deklaracje w gameplay.h nie mają pasujących definicji w gameplay.cpp. Opublikuj plik h, aby łatwiej było go zobaczyć. –

+0

Mam podobny problem i został rozwiązany przez a) definiowanie funkcji C przed definicją metody C++, która go używała. b) prefiks :: do odwołań do funkcji C w kodzie C++. –

Odpowiedz

10

pan zdefiniował wolnostojące funkcja

void deal(vector <card> &deck, vector <player> players){ 
for(int j = 0; j<4; j++){ 
    for(int i = 0; i<13; i++){ 
    players.at(j).addCard(deck.at(0)); 
    deck.erase(deck.begin()); 
    } 
} 
} 

natomiast Przypuszczam, że ma na celu zdefiniowanie funkcji członka gameplay::deal

void gameplay::deal(vector <card> &deck, vector <player> players){ 
//... 
} 

Jak jmp poprawnie zauważył w komentarzu, to samo dotyczy funkcji score.

Przekazałbym również players przez odniesienie, ponieważ wydaje się, że wywołuje on addCard() na odtwarzaczach, co oznacza (przypuszczam), że potrzebny jest zmieniony przekazany parametr.

+1

To samo dotyczy "wyniku". – jpm

+0

To działało idealnie dla mojego kodu, ale mam ten ostatni nieznośny błąd, którego nie rozumiem. Po próbie połączenia i kompilacji pojawia się następujący błąd. ./ccEKgSTO.o: W funkcji 'gamePlay :: gamePlay() ': > main.cpp :(. text._ZN8gamePlayC1Ev [gamePlay :: gamePlay()] + 0x7b): niezdefiniowane odniesienie do' card :: card() ' –

+0

@PeterBlum: Czy podałeś definicję (implementację) konstruktora klasy karty? –

Powiązane problemy