问题:
类模板中成员函数的创建时机:调用阶段。解决:
导致分文件编写时链接不到。
- 解决方案1:直接包含.cpp源文件。把include "Person.h"变为 include “Person.cpp”。
- 解决方案2:将声明.h文件和实现.cpp文件写到同一个文件中,并更改后缀名为.hpp,hpp是约定的名称,并不是强制。
#pragma once
#include
using namespace std;
template
class Person
{
public:
Person(T1 name, T2 age);
void showPerson();
private:
T1 m_Name;
T2 m_Age;
};
源文件Person.cpp中代码:
#include "Person.h"template
Person::Person(T1 name, T2 age)
{
this->m_Name = name;
this->m_Age = age;
}
template
void Person::showPerson()
{
cout << "姓名:" << this->m_Name << ", 年龄:" << this->m_Age << endl;
}
源文件程序入口函数中
#include
using namespace std;
#include "Person.h"void test01()
{
Person p("孙悟空", 999);
p.showPerson();
}int main()
{
test01();
system("pause");
return 0;
}
错误信息:
文章图片
LNK2019 无法解析的外部符号 "public: __thiscall Person,class std::allocator >,int>::Person,class std::allocator >,int>(class std::basic_string,class std::allocator >,int)" (??0?$Person@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@Z),函数 "void __cdecl test01(void)" (?test01@@YAXXZ) 中引用了该符号 01模板
LNK2019 无法解析的外部符号 "public: void __thiscall Person,class std::allocator >,int>::showPerson(void)" (?showPerson@?$Person@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@@QAEXXZ),函数 "void __cdecl test01(void)" (?test01@@YAXXZ) 中引用了该符号
LNK1120 2 个无法解析的外部命令
三个错误如上所示。调用阶段,导致分文件编写时链接不到。
解决方案 上面提到了两种:
解决方案一:直接包含源文件。 第一种将程序入口中的头文件
#include "Person.h"
写成
#include "Person.cpp"
问题得到解决。
类模板中的成员函数创建时机:是在调用时才分配内存。分析: 我们在程序中写包含头文件Person.h文件,编译中,无法生成成员函数。因为编译器没有见到过,所以编译器也不会去找这两个函数,也不会创建,为其分配内存。所以会报错。链接阶段解析不到。
如果我们在程序中直接包含.cpp文件(#include “Person.cpp”),相当于直接让编译器去看cpp中的代码,编译器见过这些代码,在Person.cpp中,又有包含头文件(#include "Person.h"),那么编译器相当于把所有东西都看了一遍。这样就可以正常调用。
这样的做法很少用,因为很少有直接让人看源码的。所以第二种解决方式,才是常用的。解决方案二:
分开写,由于创建时机的问题。导致无法链接到。将声明和实现写到同一个文件中,并更改后缀名为.hpp
将.h和.cpp中的内容写到一起,将后缀名改为.hpp文件。只要写hpp文件,别人一看就知这事类模板。约定俗成。将Person.cpp的代码直接复制到Person.h文件中,然后将Person.h文件重命名为Person.hpp。
用的时候,在程序中直接引用hpp文件。
#include "Person.hpp"
类模板文件Person.hpp文件内容:
#pragma once
#include
using namespace std;
template
class Person
{
public:
Person(T1 name, T2 age);
void showPerson();
private:
T1 m_Name;
T2 m_Age;
};
// 类外实现
template
Person::Person(T1 name, T2 age)
{
this->m_Name = name;
this->m_Age = age;
}
template
void Person::showPerson()
{
cout << "姓名:" << this->m_Name << ", 年龄:" << this->m_Age << endl;
}
此时程序可以正常执行。
总结: 类模板中的成员函数创建时机是在:调用阶段,导致分文件编写时,无法链接到源文件。
为此两种解决方案:
- 第一种:直接引用源文件,
- 第二种:将类模板的声明和实现放在一个文件中,后缀名按照编程规范以.hpp结尾。
【C++|C++模板笔记八(类模板分文件编写)】
推荐阅读
- C++|C++模板笔记六(类模板与继承;)
- C++学习笔记|C++内存管理笔记
- c++|C++读书笔记(模板)
- C++|C++学习笔记9 模板
- python|编程开源_开源社区在编程中的方式和方式
- 蓝桥杯真题题解|蓝桥杯2015初赛-奖券数目-枚举
- 数据结构|数据结构 (栈)迷宫求解(c++版本)
- 数据结构|数据结构二叉树的基础操作( 1.创建二叉树2.先序遍历3.中序排序4.后序遍历 5.层序遍历6. 统计节点的数目 7.交换左右子树 8.计算并输出该二叉树的
- java|2022年支付宝集五福|看这里100%扫敬业福