C++多个C++文件-ld:找不到体系结构x86_64的符号

C++ multiple c++ files - ld: symbol(s) not found for architecture x86_64

本文关键字:C++ 符号 x86 找不到 多个 文件 -ld 体系结构      更新时间:2023-10-16

可能重复:
为什么模板只能在头文件中实现?

当我将Stack.cpp放入Stack.h时,它运行得很好,但当我分离Stack.h和.cpp文件时,它会出现此错误。我还有一个main.cpp文件,它什么都不做,只包括AlgebraicExpression.h我用这个命令编译:"g++-o main main.cpp代数表达式.cpp堆栈.cpp">

Undefined symbols for architecture x86_64:   "Stack<char>::pop()", referenced from:
      infix2postfix(char*) in ccKgncmm.o   "Stack<char>::top()", referenced from:
      infix2postfix(char*) in ccKgncmm.o   "Stack<char>::push(char)", referenced from:
      infix2postfix(char*) in ccKgncmm.o   "Stack<char>::size()", referenced from:
      infix2postfix(char*) in ccKgncmm.o   "Stack<char>::Stack()", referenced from:
      infix2postfix(char*) in ccKgncmm.o   "Stack<double>::pop()", referenced from:
      evaluatePostfix(char*) in ccKgncmm.o   "Stack<double>::top()", referenced from:
      evaluatePostfix(char*) in ccKgncmm.o   "Stack<double>::push(double)", referenced from:
      evaluatePostfix(char*) in ccKgncmm.o   "Stack<double>::Stack()", referenced from:
      evaluatePostfix(char*) in ccKgncmm.o ld: symbol(s) not found for architecture x86_64 collect2: ld returned 1 exit status

代数表达式.h

char* infix2postfix(char *infix);
double evaluatePostfix(char*);

Stack.h

#ifndef STACK_H
#define STACK_H
template <class T>
class Stack
{
public:
        Stack();
        void pop();
        T top();
        void push(T val);
        int size();
        T *values;
        int maxSize;
        int length;
};
#endif

代数表达式.cpp

#include "AlgebraicExpression.h"
#include "Stack.h"
using namespace std;
bool isOperator(char c)
{
        if(c=='+' || c=='-' ||
                c=='*' || c=='/')
                return true;
        return false;
}
bool isDigit(char c)
{
        if(c=='0'||(c>='1'&&c<='9'))
                return true;
        return false;
}
int compareOperators(char c1,char c2)
{
        int v1,v2;
        if(!isOperator(c1) || !isOperator(c2))
                return -1;
        if(c1 == '*' || c1 =='/')v1 = 1;
        else v1 = 0;
        if(c2 == '*' || c2 == '/')v2 = 1;
        else v2 = 0;
        return v1-v2;
}
char *infix2postfix(char *infix)
{
        int lenIn,lenPost;
        for(lenIn=0,lenPost=0;infix[lenIn];++lenIn)
                if(infix[lenIn]!='('&&infix[lenIn]!=')')
                        ++lenPost;
        char *postfix = new char[lenPost+1];
        int i,j;
        Stack<char> operations;
        for(i=0,j=0;i<lenIn&&j<lenPost;++i)
                if(isDigit(infix[i]))
                        postfix[j++] = infix[i];
                else if(isOperator(infix[i]))
                {
                        while(operations.size()&&
                                compareOperators(operations.top(),infix[i])>-1)
                        {
                                postfix[j++] = operations.top();
                                operations.pop();
                        }
                        operations.push(infix[i]);
                }
                else
                {
                        if(infix[i] == '(')
                                operations.push(infix[i]);
                        else if(infix[i] ==')')
                        {
                                while(operations.size()&&operations.top()!='(')
                                {
                                        postfix[j++] = operations.top();
                                        operations.pop();
                                }
                                operations.pop();
                        }
                }
        while(operations.size())
        {
                postfix[j++] = operations.top();
                operations.pop();
        }
        postfix[j] = '';
        return postfix;
}
double evaluatePostfix(char *postfix)
{
        Stack<double> result;
        for(int i=0;postfix[i];++i)
                if(isDigit(postfix[i]))
                        result.push(postfix[i]-'0');
                else
                {
                        double n1,n2,r;
                        n1 = result.top();
                        result.pop();
                        n2 = result.top();
                        result.pop();
                        if(postfix[i] == '+')
                                r = n1+n2;
                        else if(postfix[i] == '-')
                                r = n2-n1;
                        else if(postfix[i] == '*')
                                r = n1*n2;
                        else if(postfix[i] == '/')
                                r = n1/n2;
                        result.push(r);
                }
        return result.top();
}

堆叠.cpp

#include "Stack.h"
template <class T>
Stack<T>::Stack()
{
        maxSize = 100;
        length =0;
        values = new T[maxSize];
}
template <class T>
T Stack<T>::top()
{
        return values[length-1];
}
template <class T>
void Stack<T>::push(T val)
{
        if(maxSize==length)
        {
                T *temp = new T[length*2];
                for(int i=0;i<length;++i)
                        temp[i] = values[i];
                values = temp;
                maxSize = length*2;
        }
        values[length++] = val;
}
template <class T>
void Stack<T>::pop()
{
        if(length>0)
                length--;
}
template <class T>
int Stack<T>::size()
{
        return length;
}

对于类模板,所有定义都需要在标头中。

C++常见问题解答是一本不错的读物。

基本上,当模板类被实例化时,它需要能够看到类的整个定义,而不仅仅是头部。

如果您知道类将要使用的所有类型您可以用所有这些类型实例化模板然后将定义保留在cpp中中,如本C++常见问题条目中所述

如前所述,为什么模板只能在头文件中实现?

如果您真的想分离模板头和实现文件,可以在Stack.h的底部包含Stack.cpp,它被称为The Inclusion Model

#include "Stack.cpp"

签出引用:为什么模板只能在头文件中实现?