为什么我的代码有一个" Apple Mach-O链接器错误?"

时间:2016-08-02 03:56:10

标签: c++ xcode error-handling linker

我在构建程序时遇到此错误:Apple Mach-O Linker (ld) Error Linker Command failed with exit code 1。通常当我尝试修复此错误时,因为具有main函数的文件是#include - 不止一次的文件。但是,我不相信这次就是这种情况。 X代码也通知我duplicate symbol _passed in: ranker.oolympic.o

//competitor.h

#ifndef __Olympic_Lab__competitor__
#define __Olympic_Lab__competitor__

#include <iostream>
using namespace std;
 class Competitor {
     char* name = nullptr;
     int laneAssignment;    
     float time;
 public:
    Competitor(char n[], int lane);
    ~Competitor();
    void setTime(float f);
    char* getName(){    return name;    }
    int getLane(){      return laneAssignment;    }
    float getTime(){    return time;    }
    void print(){   cout << name << endl;    }
 };
#endif 

//competitor.cpp

#include "competitor.h"
Competitor::Competitor(char n[], int lane){
    name = n;
    laneAssignment = lane;
}
Competitor::~Competitor(){
    //does nothing for now
}
void Competitor::setTime(float t){
    time = t;
}

//ranker.h

#ifndef __Olym__ranker__
#define __Olym__ranker__
#include <vector>
#include "competitor.h"
using namespace std;
int passed = 0;
class Ranker {
    bool boolean = true;
public:
    vector<Competitor*> rv;
    Ranker(int lanes);
    ~Ranker();
    int addList(Competitor* c);
    Competitor* getLane(int lane);
    Competitor* getFinish(int finish);
    int getFilled();
};
#endif

//ranker.cpp

#include "ranker.h"
Ranker::Ranker(int lan){
    rv.resize(lan - 1);
    for(int i = 0; i <= rv.size(); i++){
        rv[i] = nullptr;
    }
}
Ranker::~Ranker(){
    for(int i = 0; i <= rv.size(); i++){
        delete rv[i];
    }
}
int Ranker::addList(Competitor *c){
    if(c != NULL && passed <= 4){
        rv[passed++] = c;
        return passed - 1;
    }
    return 0;
}
 Competitor* Ranker::getLane(int lane){
    for(int i = 0; i <= rv.size(); i++){
        if(rv[i]->getLane() == lane && rv[i] != NULL){
            return rv[i];
        }
    }
    return rv[0];
}
Competitor* Ranker::getFinish(int finish){
    if(boolean){
        Competitor *temp = nullptr;
        int highestIndex;
        for(int i = rv.size(); i >= 0; i--){
            highestIndex = i;
            for(int j = i; j >= 0; j--){
                if(rv[j] != nullptr && rv[highestIndex] != nullptr){
                    if(rv[j]->getTime() > rv[highestIndex]->getTime())
                        highestIndex = j;
                }
            }
            temp = rv[i];
            rv[i] = rv[highestIndex];
            rv[highestIndex] = temp;   
        }
        delete temp;
        temp = *new Competitor*;
        boolean = false;
    }
    return rv[finish - 1];
}
int Ranker::getFilled(){
    int filled = 0;
    for(int i = 0; i <= rv.size(); i++){
        if(rv[i] != NULL){
            filled++;
        }
    }
     return filled;
}

//olympic.h

#ifndef _Olympic_Lab__olympic__
#define _Olympic_Lab__olympic__
#include "ranker.h"
#endif

//olympic.cpp

#include "olympic.h"

 int main(){
    const int lanes = 4;
    Ranker rank(lanes);
    Competitor* starters[4];
    starters[0] = new Competitor("EmmyLou Harris", 1);
    starters[1] = new Competitor("Nanci Griffith", 2);
    starters[2] = new Competitor("Bonnie Raitt", 3);
    starters[3] = new Competitor("Joni Mitchell", 4); 
    starters[0]->setTime((float)12.0);
    starters[1]->setTime((float)12.8);
    starters[2]->setTime((float)11.0);
    starters[3]->setTime((float)10.3);
    for(int i = 0; i < lanes; i++){
        rank.addList(starters[i]);
    }
    cout << "Competitors by lane are:" << endl;
    for(int i = 1; i <= lanes; i++)
        rank.getLane(i)->print();
    cout << "Rankings by finish are:" << endl;
    for(int i = 1; i <= lanes; i++)
        rank.getFinish(i)->print();
    for(int i = 0; i < lanes; i++){
        delete starters[i];
    }
}

如果有人能帮我找到完全导致此错误的原因,我们将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:1)

如果在标题中声明变量,它将在包含标题的每个文件中重复。

所以在Ranker.h中int passed = 0;会给你带来很多悲伤。 ranker和olympian都分配了不同的passed,而链接器现在也不知道哪一个是真正的传递。

所以你可能想要的是

extern int passed;
在ranker.h中

声明传递将在某个时刻存在,如果它还没有,那么它不需要被分配。编译器将很乐意继续使用passed

然后在ranker.cpp中,声明

int passed = 0;

分配passed并满足链接器。现在你只有一个passed,任何包含ranker.h的人都可以查看和使用它。

如果您需要多个passed,则必须执行其他操作,以便他们不会共享相同的名称和范围,但这看起来不像您的目标。

偏离主题:抵制将using namespace std;放入头文件的冲动。它可能导致将来很难调试的问题。更多信息:Why is "using namespace std" considered bad practice?