Что вызывает ошибку сборки «Неопределенные символы для архитектуры x86_64»? - PullRequest
3 голосов
/ 14 марта 2012

это отрывок из программы, над которой я работал. Я подозреваю, что проблема может быть вызвана этим членом класса Player:

std::vector<std::list<Bid> > lBidding

Код приводит к следующей ошибке сборки:

g++ -o ./Debug/fudge @"/Users/andvik/MockUp/fudge/fudge.txt"-L.   
Undefined symbols for architecture x86_64:
"Player::lBidding", referenced from:
  Deal::bidding()     in MockUp_main.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make[1]: *** [Debug/fudge] Error 1
make[1]: Leaving directory `/Users/andvik/MockUp/fudge'
make: *** [All] Error 2
make: Leaving directory `/Users/andvik/MockUp'
----------Build Ended----------
0 errors, 0 warnings

Я чувствую себя довольно уверенно, что эта ошибка как-то связана со статическим вектором, поскольку это был последний фрагмент кода, который я добавил. Мое исследование показало множество различных проблем, приводящих к схожим ошибкам, но ни одна из них не связана с тем же типом кода, который у меня есть.

Код: (Я обрезал несколько строк кода, которые, кажется, не применяются. Это должен быть минимум).

#include <string>
#include <list>
#include <vector>

class Bid
{
public:
short iLevel;
short iSuit;
Bid():iLevel(0),iSuit(0){};
Bid(short l, short s):iLevel(l),iSuit(s){};
bool operator ==(const Bid Other) const
{
    if(iLevel==Other.iLevel && iSuit==Other.iSuit)
    {return 1;}
    else{return 0;}
}
};
class Player
{
public:
short iPos;
static std::vector<std::list<Bid> > lBidding;
Player(short p):iPos(p) {};

bool operator ==(const Player Other) const
{
    if(iPos == Other.iPos){return 1;}
    else{return 0;
    }
}
};
class Deal
{
public:
short iPass;
short iIteration;
Player pWest, pNorth, pEast, pSouth, pError;
Deal(): iPass(0), iIteration(0), pWest(0), pNorth(1), pEast(2), pSouth(3), pError(5){};
void bidding()
{
    Player pTemp(5);
    Bid bTemp, bPass;
    while(iPass < 3)
    {
        pTemp = setPlayer();

                    if(pTemp == pError){break;} 

        if(Player::lBidding.at((pTemp.iPos+2)%4).empty()){}
        else
        {
            if(Player::lBidding.at(pTemp.iPos).empty()){}
        }
        if(bTemp == bPass){++iPass;}
        else{(*Player::lBidding.begin()).push_back(bTemp);}
    };
}
Player setPlayer()
{
    switch(iIteration % 4)
    {
        case 0: return pWest; break;
        case 1: return pNorth; break;
        case 2: return pEast; break;
        case 3: return pSouth; break;
    }
    return pError;
}
};
int main(int argc, char **argv)
{
srand(time(0));
Deal deal;
deal.bidding();
printf("No debugging error.\n");
return 0;
}

Так что кто-то может сказать мне, что не так с моим кодом и почему. Кстати, если кому-то интересно, это составляет основную часть самодельного симулятора Бриджа.

1 Ответ

7 голосов
/ 14 марта 2012

Причина в том, что lBidding является статическим, но вы объявляете, а не реализует . Если вы просто добавите;

std::vector<std::list<Bid> > Player::lBidding;

до конца файла, все счастливо собирается.

Поскольку статические переменные не являются частью объекта, а вместо класса, вам необходимо реализовать их один раз в файле cpp, обычно по соглашению с именем .cpp. Не стоит помещать его в файл .h, поскольку это будет реализовывать его в каждом файле, который его включает, и приведет к (оправданным) ошибкам компоновщика.

...