链接目标文件时g ++ / make失败

时间:2014-03-17 00:11:13

标签: c++ makefile

所以,我正在尝试学习c ++和一些关于makefile的知识。但是,出于某种原因,我无法正确链接我的文件。 makefile如下:

OBJS = stl_test.o src/t_stack.o src/matrix_w.o src/matrix.o

stl_test: $(OBJS) 
    g++ -o stl_test $(OBJS) -lm

.cpp.o:
    g++ -c -O -I. $< -o $@ -std=c++0x

stl_test.o: include/t_stack.h

src/matrix.o: include/matrix.h

src/matrix_w.o: include/matrix_w.h

src/t_stack.o: include/t_stack.h

include/matrix_w.h: include/matrix.h
    touch include/matrix_w.h

include/t_stack.h: include/matrix_w.h include/matrix.h
    touch include/t_stack.h

我目前遇到的问题如下:

touch include/matrix_w.h
touch include/t_stack.h
g++ -c -O -I. stl_test.cpp -o stl_test.o -std=c++0x
g++ -c -O -I. src/t_stack.cpp -o src/t_stack.o -std=c++0x
g++ -c -O -I. src/matrix_w.cpp -o src/matrix_w.o -std=c++0x
g++ -c -O -I. src/matrix.cpp -o src/matrix.o -std=c++0x
g++ -o stl_test stl_test.o src/t_stack.o src/matrix_w.o src/matrix.o -lm
src/t_stack.o: In function `T_stack::pop()':
t_stack.cpp:(.text+0xc9): undefined reference to `Matrix<double>::display() const'
t_stack.cpp:(.text+0xd7): undefined reference to `Matrix<double>::~Matrix()'
src/t_stack.o: In function `T_stack::push_translation(double, double, double)':
t_stack.cpp:(.text+0x1af): undefined reference to `Matrix<double>::Matrix(int, int, double*)'
t_stack.cpp:(.text+0x239): undefined reference to `Matrix<double>::multiply(Matrix<double>*) const'
src/t_stack.o: In function `T_stack::push_scaling(double, double, double)':
t_stack.cpp:(.text+0x33f): undefined reference to `Matrix<double>::Matrix(int, int, double*)'
t_stack.cpp:(.text+0x3c9): undefined reference to `Matrix<double>::multiply(Matrix<double>*) const'
src/t_stack.o: In function `T_stack::T_stack()':
t_stack.cpp:(.text+0x4f4): undefined reference to `Matrix<double>::Matrix(int, int, double*)'
t_stack.cpp:(.text+0x516): undefined reference to `Matrix<double>::copy() const'
src/t_stack.o: In function `T_stack::~T_stack()':
t_stack.cpp:(.text+0x64c): undefined reference to `Matrix<double>::display() const'
t_stack.cpp:(.text+0x65a): undefined reference to `Matrix<double>::~Matrix()'
t_stack.cpp:(.text+0x74f): undefined reference to `Matrix<double>::display() const'
collect2: ld returned 1 exit status
make: *** [stl_test] Error 1

我不完全确定问题是什么。我尝试在g ++命令中更改文件的顺序但是也没有用。我已经尝试检查文件的标题,我认为它们是正确的,但我已经在这里发布了片段:

stltest.cpp

#include <iostream>

#include "include/t_stack.h"

using namespace std;

int main(void) {
......

matrix.h

#ifndef _MATRIX_
#define _MATRIX_

#include <iostream>

using namespace std;
......

matrix_w.h

#ifndef _MATRIX_W_
#define _MATRIX_W_

#include "include/matrix.h"

class Matrix_w {
......

t_stack.h

#ifndef _T_STACK_H_
#define _T_STACK_H_

#include <list>
#include <stack>
#include <iostream>
#include "include/matrix.h"
#include "include/matrix_w.h"

using namespace std;

class T_stack {
    private:
        // matrix stack
        stack<Matrix_w*, list<Matrix_w* > >* m_stack;
        // inverse transform list
        list<Matrix<double>* >* t_list;
    public:
        T_stack();
        void pop();
        void push_translation(double tx, double ty, double tz);
        void push_scaling(double sx, double sy, double sz);
        int size() const;
        ~T_stack();
};

#endif

任何想法可能是什么问题?谢谢!

以防万一,这里是它所抱怨的方法的实现(该文件名为matrix.cpp)..

#include "include/matrix.h"

using namespace std;

template <typename T>
Matrix<T>::~Matrix() {
    delete data;
}

template <typename T>
Matrix<T>::Matrix(int width, int height) {
    this->height = height;
    this->width = width;
    this->data = new T[height*width];
}

template <typename T>
Matrix<T>::Matrix(int width, int height, T* data) {
    this->height = height;
    this->width = width;
    this->data = new T[height*width];

    int i;
    //may be able to speed this up by using memcpy
    // Not sure whether this is a good idea anyways
    for(i=0; i < height*width; i++) {
        this->data[i] = data[i];
    }
}

template <typename T>
T Matrix<T>::at(int x, int y) const {
    #ifdef __DEBUG
        if(x < width && y < height) {
            return data[y*width + x];
        } else {
            throw 1;
        }
    #else
        return data[y*width + x];
    #endif
}

template <typename T>
void Matrix<T>::set(int x, int y, T val) {
    #ifdef __DEBUG
        if(x < width && y < height) {
            data[y*width + x] = val;
        } else {
            throw 1;
        }
    #else
        data[y*width + x] = val;
    #endif
}

//this function is just for convenience but it should only work
//when T is some number type ----ASK!!
template <typename T>
void Matrix<T>::display() const {
    int i, j;

    cout << "[" << endl;
    for(i=0; i<height; i++) {
        for(j=0; j<width; j++) {
            cout << " " << data[i*width + j];
        }
        cout << endl;
    }
    cout << "]" << endl;
}

template <typename T>
Matrix<T>* Matrix<T>::multiply(Matrix<T>* other) const {
    #ifdef __DEBUG
        if(other->height != width) {
            throw 1;
        }
    #endif

    T* res = new T[other->width*height];
    int i,j,k;
    T sum;

    for(i=0; i<height; i++) {
        for(j=0; j<other->width; j++) {
            sum = 0;
            for(k=0; k<width; k++) {
                sum += other->data[k*other->width+j]*data[i*width+k];
            }
            res[i*other->width + j] = sum;
        }
    }

    return new Matrix<double>(other->width, height, res);
}

template <typename T>
Matrix<T>* Matrix<T>::copy() const {
    return new Matrix<T>(width, height, data);
}

2 个答案:

答案 0 :(得分:1)

当你有一个模板类或函数时,这些函数应该是内联的,并且正文应该在头文件中,在类中或在类外面使用inline关键字。

不同之处在于,与常规类不同,编译器正在为您用作模板类型的每种类型编译类。

如果您根本不使用它,该文件甚至不会被编译一次。

在几个编译器中,即使将代码拆分为h和cpp,代码也能正常工作。但你不能指望它。

答案 1 :(得分:1)

我知道,将模板实现为内联函数通常是典型的。但是,您可以在matrix.cpp文件中使用模板的显式实例化。在底部,在定义之后,您可以尝试添加:

   template class Matrix<double>;

如果您没有使用预编译的标头,这实际上可能很有意义。此外,它可以在我想的任何地方进行,但是每个程序只能有一个这样的语句,如果你在两个地方实例化一个矩阵,它可能会也可能不起作用。