C++模板类的分离编译问题

今天在用C++复现数据结构与算法的C代码时, 遇到了关于模板类的问题


问题

当前复现线性表(LinearList), 目前一共三个文件

  • LinearList.h: 线性表模板类的声明

    #ifndef LINEARLIST_H
    #define LINEARLIST_H
    
    template <typename T>
    class LinearList
    {
    private:
        T* array;
        int length;
    public:
        LinearList(int length);
        ~LinearList();
    };
    
    #endif
    
  • LinearList.cpp: LinearList.h的实现

    #include "LinearList.h"
    #include <iostream>
    
    template <typename T>
    LinearList<T>::LinearList(int length)
    {
        this->array = new T[length];
        this->length = length;
        for (int i = 0; i < length; i++)
        {
            std::cin >> *(array + i);
        }
        std::cout << "Created Successfully!\n";
    }
    
    template <typename T>
    LinearList<T>::~LinearList()
    {
        delete[] this->array;
        this->array = nullptr;
    }
    
  • test.cpp: 测试数据结构定义是否正确

    #include <iostream>
    #include "LinearList.h"
    
    int main()
    {
        LinearList<int> A(3);
        return 0;
    }
    

使用g++编译

g++ LinearList.cpp test.cpp -o test

发现报错:

/usr/bin/ld: /tmp/ccnN4cn1.o: in function `main':
test.cpp:(.text+0x29): undefined reference to `LinearList<int>::LinearList(int)'
/usr/bin/ld: test.cpp:(.text+0x75): undefined reference to `LinearList<int>::~LinearList()'
/usr/bin/ld: test.cpp:(.text+0x9b): undefined reference to `LinearList<int>::~LinearList()'
collect2: error: ld returned 1 exit status

解决办法

所有的C++编译器都不支持模板类的分离式编译, 所以只能将模板类的函数实现也写在头文件.h中

  • LinearList.h
    #ifndef LINEARLIST_H
    #define LINEARLIST_H
    
    #include <iostream>
    
    template <typename T>
    class LinearList
    {
    private:
        T* array;
        int length;
    public:
        LinearList(int length);
        ~LinearList();
        int get_length();
    };
    
    template <typename T>
    LinearList<T>::LinearList(int length)
    {
        this->array = new T[length];
        this->length = length;
        for (int i = 0; i < length; i++)
        {
            std::cin >> *(array + i);
        }
        std::cout << "Created Successfully!\n";
    }
    
    template <typename T>
    LinearList<T>::~LinearList()
    {
        delete[] this->array;
        this->array = nullptr;
    }
    
    #endif
    

其他注意事项

记得头文件定义类的时候要加如下结构, 作用是防止编译预处理时多次引入导致重复定义

#ifndef XXX
#define XXX

/*
  code here
*/

#endif // end define XXX
posted @ 2022-06-26 11:52  EvanZone  阅读(80)  评论(0编辑  收藏  举报