2016-08-02 4 views
1

프로그램을 빌드 할 때이 오류가 발생합니다 : Apple Mach-O Linker (ld) ErrorLinker Command failed with exit code 1. 대개이 오류를 수정하려고하면 주 기능이있는 파일이 #include - 두 번 이상 파일에 저장됩니다. 그러나, 나는 이것이 이번에는 사실이라고 생각하지 않는다. 또한 X 코드에 의해 duplicate symbol _passed in:ranker.oolympic.o이라는 알림을 받았습니다. 누군가가 정확히이 오류의 원인을 을 찾는 도와주세요 수 있다면내 코드에 "Apple Mach-O Linker Error"가 나타나는 이유는 무엇입니까?

//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

변수를 헤더에 선언하면 해당 변수가 헤더를 포함하는 모든 파일에 복제됩니다.

ranker.h의 int passed = 0;은 많은 슬픔을 줄 것입니다. ranker와 olympian은 모두 다른 passed을 할당했으며 링커는 실제 전달 된 단서가 없습니다.

그래서 아마 당신은 원하는 것을 ranker.h에서

extern int passed; 

그것은 아직 않는 경우 즉, 어떤 점에서 존재하게 전달 선언하는 것입니다, 그래서 할당 할 필요가 없습니다. 컴파일러는 계속 행복하게 수행하고 passed을 사용할 수 있습니다.

그리고 ranker.cpp에서

int passed = 0; 

passed 할당 링커를 만족 선언. 이제 passed 하나만 있고 ranker.h를 포함하는 모든 사용자는이를보고 사용할 수 있습니다.

passed 하나 이상을 원하면 동일한 이름과 범위를 공유하지 않도록 다른 작업을해야하지만 이는 목표와 다르게 나타납니다.

주제 끄기 : using namespace std;을 헤더 파일에 넣으십시오. 디버깅하기가 매우 어려울 수있는 미래의 문제가 발생할 수 있습니다. 더보기 : Why is "using namespace std" considered bad practice?

관련 문제