2015-09-05 78 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”关键字以防止一个定义规则违例(根据需要使用来自多个源文件的模板)。

相关问题