首页  >  问答  >  正文

c++ - 为什么包含.h文件报错,包含.cpp文件却可以?!

头文件:XXX.h

#ifndef QUEUE_BUFFER_H_
#define QUEUE_BUFFER_H_


template<typename T>
struct Buffer
{
    T _data;
    int _BufNo;
    Buffer *next;
    Buffer(int No, T data): _data(data), _BufNo(No), next(NULL) {}
};

template<typename T>
class Buffer_Queue
{
private:
    int _length; // 队列元素个数
    Buffer<T> *front; // 队列的头指针
    Buffer<T> *rear;  // 队列的尾指针
    bool isEmpty() const; // 判断队列是否为空
public:
    Buffer_Queue(T data, int length = 10); // 构造函数
    ~Buffer_Queue();
    Buffer<T> *getbuf(); // 获得空的buffer(出队)
    void putbuf(Buffer<T> *buf); // 挂载到队尾(入队)
    

    void display(); // 测试输出

};

#endif

定义:XXX.cpp

#include <cstdlib>
#include <iostream>
#include "queue_buffer.h"

using std::cout;
using std::endl;
using std::cerr;


template<typename T>
Buffer_Queue<T>::Buffer_Queue(T data, int length): _length(length) // 构造函数
{
    front = rear = NULL;        
    int i = 0;

    if (i < _length)
    {
        // 分配第一个结点
        Buffer<T> *p = new Buffer<T>(i++, data);
        if (!p) 
        {
            cerr << "Memory alloc failed" << endl;
            exit(1);
        }
        front = rear = p;
        front->next = NULL; // 多余
    }


    while (i < _length)
    {
        Buffer<T> *p = new Buffer<T>(i++, data);
        if (!p)
        {
            cerr << "Memory alloc failed" << endl;
            exit(1);
        }
        rear->next = p;
        rear = p;
    }
        
}

template<typename T>
bool Buffer_Queue<T>::isEmpty() const
{
    return _length == 0;    
}

template<typename T>
Buffer<T> * Buffer_Queue<T>::getbuf() // 出队
{
    if (isEmpty())    // 如果队列为空,则返回NULL
        return NULL;

    Buffer<T> *p = front;
    front = front->next;
    _length--;
    p->next = NULL;
    if (rear == p) // 只有一个结点
        rear = front;

    return p;
}

template<typename T>
void Buffer_Queue<T>::putbuf(Buffer<T> *buf) // 入队
{
    if (isEmpty())    // 如果队列为空
    {
        front = rear = buf;
        front->next = NULL;
        ++_length;
    }

    // 队列不为空
    rear->next = buf;
    rear = buf;
    rear->next = NULL;
    ++_length;
}

template<typename T>
void Buffer_Queue<T>::display()
{
    Buffer<T> *curr = front; 
    while (curr)
    {
        cout << curr->_BufNo << ": " << curr->_data << endl;    
        curr = curr->next;
    }
}

template<typename T>
Buffer_Queue<T>::~Buffer_Queue()
{
    Buffer<T> *curr = NULL;
    while (front)
    {
        curr = front;
        front = front->next;
        delete curr;
    }
}

测试:test.cpp

#include <iostream>
#include "queue_buffer.h"

int main(void)
{
    Buffer_Queue<int> test(-1); // 10个

    test.display();

    Buffer<int> *p = new Buffer<int>(10, -1);
    test.putbuf(p);

    Buffer_Queue<int> temp(-1, 0); // 0个
    temp.putbuf(p);

    test.display();
    temp.display();

    return 0;
}

编译: g++ xxx.cpp test.cpp -o test
test.cpp文件中包含xxx.h就报错,undefined reference to XXXXXXXX(是调用的那些函数)
test.cpp文件中包含xxx.cpp就不会报错,一切正常

伊谢尔伦伊谢尔伦2765 天前686

全部回复(2)我来回复

  • 高洛峰

    高洛峰2017-04-17 13:17:27

    1. include并不关心是h还是cpp,还是ini, 他只是打开那个文件, 展开在当前这个文件里面
      你可以用g++ -E 编译一下, 看到真实编译的最终文件

    2. 链接错误吗....因为你的头文件里面写着模板类, 然而现在所有的C++编译器, 都不支持模板分离编译, 也就是说, 函数的实现得写在头文件里面去

    回复
    0
  • PHP中文网

    PHP中文网2017-04-17 13:17:27

    根据我在学生时期通过同学积累下来的丰富的C++经验,我认为你的头文件里面用了iostream的东西。XXX.cpp没挂是因为你替他include了iostream。

    回复
    0
  • 取消回复