错误原因LNK2019 无法解析的外部符号 “public: __cdecl Father::Father(int)” (??0?KaTeX parse error: Undefined control sequence: Microsoft at position 48: …该符号 Project9 E:̲M̲i̲c̲r̲o̲s̲o̲f̲t̲ ̲Visual Studioc…Father@H@@QEBA?AV0@AEBV0@@Z),函数 main 中引用了该符号 Project9 E:Microsoft Visual StudiocodeProject9main.obj 1
错误
LNK2019 无法解析的外部符号 "public: void __cdecl Father::prfT(void)const " (?prfT@?$Father@H@@QEBAXXZ),函数 main 中引用了该符号 Project9 E:Microsoft Visual StudiocodeProject9main.obj 1
C++中类模板比较特殊会二次编译,所以分文件编写时编译器找不到成员函数的实现
代码: 文件结构
Father.h#pragma once templateFather.cppclass Father { public: Father(T a); T getA()const; Father operator+(const Father& other) const; void prfT() const; private: T a; };
#includemain.cpp#include "Father.h" // 类成员函数需要加类模板声明 template Father ::Father (T a) { // 作用域需要加虚拟参数列表 this->a = a; } template T Father ::getA()const { return a; } template Father Father ::operator+(const Father & other) const { // 返回值是类对象也需要加虚拟参数列表 // 成员函数的参数是类对象也需要加虚拟参数列表 // 成员函数类参数列表可以不加 // 普通类型-》类类型,等同于 Father(T),调用带参构造函数 Father temp = this->getA() + other.getA(); return temp; } template void Father ::prfT() const { std::cout << a << std::endl; }
#include "Father.h"
int main() {
Father f1(12);
Father f2(13);
Father f3 = f1 + f2;
f3.prfT();
return 0;
}
解决方案:
1、把主函数放在类模板实现中,就是放在Father.cpp文件中
Father.h
#pragma once templateFather.cppclass Father { public: Father(T a); T getA()const; Father operator+(const Father& other) const; void prfT() const; private: T a; };
#include2、把类模板声明和实现放在同一个文件中,文件名使用hpp后缀 Father.hpp#include "Father.h" // 类成员函数需要加类模板声明 template Father ::Father (T a) { // 作用域需要加虚拟参数列表 this->a = a; } template T Father ::getA()const { return a; } template Father Father ::operator+(const Father & other) const { // 返回值是类对象也需要加虚拟参数列表 // 成员函数的参数是类对象也需要加虚拟参数列表 // 成员函数类参数列表可以不加 // 普通类型-》类类型,等同于 Father(T),调用带参构造函数 Father temp = this->getA() + other.getA(); return temp; } template void Father ::prfT() const { std::cout << a << std::endl; } int main() { Father f1(12); Father f2(13); Father f3 = f1 + f2; f3.prfT(); return 0; }
#pragma once #includemain.cpptemplate class Father { public: Father(T a); T getA()const; Father operator+(const Father& other) const; void prfT() const; private: T a; }; // 类成员函数需要加类模板声明 template Father ::Father (T a) { // 作用域需要加虚拟参数列表 this->a = a; } template T Father ::getA()const { return a; } template Father Father ::operator+(const Father & other) const { // 返回值是类对象也需要加虚拟参数列表 // 成员函数的参数是类对象也需要加虚拟参数列表 // 成员函数类参数列表可以不加 // 普通类型-》类类型,等同于 Father(T),调用带参构造函数 Father temp = this->getA() + other.getA(); return temp; } template void Father ::prfT() const { std::cout << a << std::endl; }
#include "Father.hpp"
int main() {
Father f1(12);
Father f2(13);
Father f3 = f1 + f2;
f3.prfT();
return 0;
}
3、类模板声明和实现还是分文件,但是实现文件后缀改成hpp,主函数文件导入hpp文件而不是.h头文件(常用)
文件结构
Father.h
#pragma once templateFather.hppclass Father { public: Father(T a); T getA()const; Father operator+(const Father& other) const; void prfT() const; private: T a; };
#includemain.cpp#include "Father.h" // 类成员函数需要加类模板声明 template Father ::Father (T a) { // 作用域需要加虚拟参数列表 this->a = a; } template T Father ::getA()const { return a; } template Father Father ::operator+(const Father & other) const { // 返回值是类对象也需要加虚拟参数列表 // 成员函数的参数是类对象也需要加虚拟参数列表 Father temp = this->getA() + other.getA(); // 成员函数类参数列表可以不加 return temp; } template void Father ::prfT() const { std::cout << a << std::endl; }
#include "Father.hpp"
int main() {
Father f1(12);
Father f2(13);
Father f3 = f1 + f2;
f3.prfT();
return 0;
}



