C++如何修正在.cpp文件中实现的友元模板函数链接错误
问题原因
链接错误核心来自两个问题:
- C++模板的默认规则是实现必须对调用方可见才能隐式实例化,如果你把模板实现放在cpp文件中,就必须手动显式实例化所有需要用到的类型。你写的
operator-显式实例化语法错误,实际只是普通函数声明,没有完成模板实例化,导致链接器找不到Array<double>对应的减法运算符实现。 - 代码中存在多处逻辑错误,即使修正实例化问题也无法正常编译。
修改步骤
1. 修正operator-的显式实例化语法
operator<<的实例化写法是正确的,operator-的写法要和它保持一致,把array.cpp末尾的:
// // T=double Array<double> operator - (const Array<double>& A, const Array<double>& B);
替换为:
// T=double 显式实例化模板 template Array<double> operator - (const Array<double>& A, const Array<double>& B);
2. 修正operator-实现中的逻辑错误
Array类只有len成员,没有rows、cols成员,构造函数只接收长度参数,所以把operator-实现里的:
Array<T> C(A.rows, A.cols);
改为:
Array<T> C(A.len);
同时在array.cpp开头引入<cassert>头文件,否则assert函数无法识别:
#include <cassert>
3. 修正析构函数的BUG
当前析构函数逻辑写反,空指针不需要释放(且delete[]空指针本身是安全的),把析构函数改为:
~Array() { delete[] data; }
4. 补充移动构造/移动赋值函数
你删除了拷贝构造和拷贝赋值函数,但operator-需要返回Array对象,需要移动语义支持,在Array类的public区域补充:
Array(Array&& arr) noexcept : len(arr.len), data(arr.data) { arr.len = 0; arr.data = nullptr; } Array& operator=(Array&& arr) noexcept { if (this != &arr) { delete[] data; len = arr.len; data = arr.data; arr.len = 0; arr.data = nullptr; } return *this; }
修改完成后重新编译即可正常运行。
内容的提问来源于stack exchange,提问作者ChrisZZ
相关产品推荐
相关产品推荐

