2015-09-05 45 views
0

我執行我的Xcode 6.2 C++程序,但我得到這個錯誤:LD:符號(S)沒有發現建築x86_64的對OSX 10.9

Undefined symbols for architecture x86_64: 
    "operator+(Stack1<int> const&, Stack1<int> const&)", referenced from: 
     _main in main.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

我不知道如何繼續在解決這個問題上,我查別人幾下就Stackoverflow.com但解決不了我的問題,

#include <iostream> 
#include <vector> 

using namespace std; 

template <class T> 
class Stack1; 

template <class T> 
Stack1<T> & operator+(const Stack1<T> &x, const Stack1<T> &y) { 
Stack1<T> z = x; 
for (unsigned int i=x.size(); i<(x.size()+y.size()); i++) { 
    z.push(y[i]); 
} 
return z; 
} 

template <class T> 
class Stack1 { 
friend Stack1<T> & operator+(const Stack1<T> &x, const Stack1<T> &y); 
private: vector <T> elems; 
public: bool empty(); 
void push(const T &item); 
T & top(); 
void pop(); 
long size(); 
}; 

template <class T> 
bool Stack1<T>::empty() { 
return elems.empty(); 
} 

template <class T> 
void Stack1<T>::push(const T &item){ 
elems.push_back(item); 
} 

template <class T> 
T &Stack1<T>::top(){ 
    return elems.back(); 
} 

template <class T> 
void Stack1<T>::pop() { 
if (!elems.empty()) 
    return elems.pop_back(); 
} 

template <class T> 
long Stack1<T>::size() { 
return elems.size(); 
} 




int main(int argc, const char * argv[]) { 
Stack1 <int> intStack; 
Stack1 <float> floatStack; 
Stack1 <string> stringStack; 
Stack1 <int> a; 
Stack1 <int> b; 

intStack.push(7); 
intStack.push(3); 
intStack.push(0); 
intStack.push(8); 

floatStack.push(0.9); 
floatStack.push(4.78); 
floatStack.push(2.157); 

stringStack.push("test1"); 
stringStack.push("abc"); 

while (!intStack.empty()) { 
    cout << "Popping from intStack: " << intStack.top() << endl; 
    intStack.pop(); 
} 

if (intStack.empty()) { 
    cout << "intStack is empty" << endl; 
} 

while (!floatStack.empty()) { 
    cout << "Popping from intStack: " << floatStack.top() << endl; 
    floatStack.pop(); 
} 

if (floatStack.empty()) { 
    cout << "floatStack is empty" << endl; 
} 

while (!stringStack.empty()) { 
    cout << "Popping from intStack: " << stringStack.top() << endl; 
    stringStack.pop(); 
} 

if (stringStack.empty()) { 
    cout << "stringStack is empty" << endl; 
} 

for (int i=0; i<3; i++) { 
    a.push(i); 
} 
for (int i=9; i>5; i--) { 
    b.push(i); 
} 
// cout << "Size of a:" << a.size(); 
Stack1 <int> c; 
c = a+b; 

while (!c.empty()) { 
    cout << "Popping from c: " << c.top() << endl; 
    c.pop(); 
} 

return 0; 
} 

得到這個錯誤:

error: failed to launch '/Users/User-name/Library/Developer/Xcode/DerivedData/4_TemplatedStack-bmcfhzdrgyhhybajmxvpyuypgmag/Build/Products/Debug/4_TemplatedStack' 
+1

在運營商+'你創建並返回類型的實例'棧1 '即使返回類型爲'堆棧&''的定義。這是不允許的 - 你返回一個對象的引用,該對象將在函數執行後被刪除。 – HelloWorld

回答

0

這裏有幾個問題你的函數定義爲operator +

  1. 您正在定義這裏 template <class T> Stack1<T> & operator+(const Stack1<T> &x, const Stack1<T> &y)operator+是一個模板的功能,但在Stack1類定義,你說 friend Stack1<T> & operator+(const Stack1<T> &x, const Stack1<T> &y); 不是模板函數,這是鏈接錯誤的原因。解決方法是在Stack1內更改爲 friend Stack1<T> operator+ <>(const Stack1<T> &x, const Stack1<T> &y);, 詳細解釋請參見isocpp FAQ

  2. 注意,你是返回參考Stack1<T> & operator+,但功能身體,你有return z,其中z是一個局部變量,只要函數調用結束後,z被破壞裏面,一個參考值將是災難性的。

  3. 您需要更改 for(unsigned int i=x.size(); i<(x.size()+y.size()); i++)for(unsigned int i=0; i<y.size(); i++),因爲你是推y[i]i不能超過y.size()更大。

  4. 您還需要爲您的班級Stack1超載運營商[]

+0

謝謝!它工作..對於點4.而不是重載操作符[]使用z.push(y.elems [i]); – PoojaChow

1

註釋中提到的問題涉及代碼中的危險錯誤,但與鏈接器問題無關。你需要做的就是添加<>operator+

friend Stack1<T> & operator+ <>(const Stack1<T> &x, const Stack1<T> &y); 

然後,long size()必須const如果你希望它是在const對象調用。

反正。請閱讀this guide on operator overloadingoperator+不應該返回一個引用,特別是一個局部變量。如果有的話,它的返回值應該是const T。還有其他的問題,但我把它作爲一個練習給你。

0

要添加到其他答案中,由於模板和模板實例化的工作方式,通常分開定義和聲明模板通常沒有意義,因爲您的定義無論如何都需要放在頭文件中以便允許它被實例化。通常,聲明和定義保持分開,以便聲明進入頭文件,而定義位於源文件中,這樣做有兩個好處:1.庫的用戶只需要頭和編譯源,所以保持它們分開允許更快速的開發(通過使用預編譯的庫)2.)在開源之外,實現代碼有時可能被隱藏,因此只有頭文件被分發。但是,對於模板而言,爲了實例化模板,定義和聲明都是必需的。正因爲如此,你只需像這樣結合的聲明和定義一起相當多的樣板和句法煩惱的保存自己:

// stack1.h 
#ifndef STACK1_H 
#define STACK1_H 

#include <vector> 

template<typename T> class Stack1 { 
public: 
    Stack1() {} 
    Stack1(const Stack1& o) : elements_(o.elements_) {} 
    Stack1(const std::vector<T>& elements) : elements_(elements) {} 
    virtual ~Stack1() {} 

    Stack1 operator+(const Stack1& o) const { 
    return Stack1(elements_ + o.elements_); 
    } 

    void push(const T& item) { elements_.push_back(item); } 
    bool empty() const { return elements_.empty(); } 
    T top() const { return elements_.back(); } 
    size_t size() const { return elements_.size(); } 
private: 
    std::vector<T> elements_; 
}; 


#endif 

雖然,它可以正確地指定定義語法模板時定義和聲明是分開的,這樣做更容易。如果確實繼續分離定義和聲明,除了其他建議之外,如果將定義放入標題中,則需要爲定義使用「inline」關鍵字以防止一個定義規則違例(根據需要使用來自多個源文件的模板)。

相關問題