吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1377|回复: 0
收起左侧

[C&C++ 转载] 剖析类模板的声明和实现分离编译的后果

[复制链接]
b917893200 发表于 2020-3-15 22:58
写程序的时候一般来说,我们在头文件里写类及其成员函数的声明,在cpp文件里写类的实现。
但是类模板有些不一样,我们通常是将声明与实现都放在一个头文件中。如果不这样做,我们看下面代码

ifndef _FUNCTION_H

define _FUNCTION_H

include<iostream>

template<typename T> class A
{
T value;
public:
T GetValue();
A(T t);
A() = default;
};

endif


这是类的声明部分代码,我们放在function.h中。

template<typename T> A<T>::A(T t) :value(t) {}
template<typename T> T A<T>::GetValue()
{
return value;
}


这是function.cpp的代码。

include<iostream>

include"function.h"

using namespace std;
int main()
{
A<int> a(5);
cout << a.GetValue();
return 0;
}


这是test.cpp,里面有我们的main函数,用以调用这个类的代码。
现在我们编译一下,
8{ZTV7SXWNHF7))}R8{4JCS.png
这个错误是发生在链接过程中的。一个c/cpp文件要经过预编译-编译-汇编三个过程,生成一个.o或。obj的目标文件,而一个exe文件就是多个.o(obj)文件合成而成。
为什么会出现这样的错误,我们到linux环境下测试。
首先我们利用g++ function.cpp -std=c++11指令将function文件编译。
1.png

可以看到并没有我们实现的函数,也就是编译器他是无法链接到的。
原因是我们的c/c++的编译机制是独立编译,也就是每个cpp独立编译,只有类实例化,模板才会实例化出相应的成员函数。
当编译main.cpp时,它实力化成A<int>类,然而,function.cpp此时并不可见,也就找不到相应的成员函数模板,就实例化不了模板函数。
当我们将function.cpp的实现放到function.h中,
g++ -S test.cpp -o test.s -std=c++1
vim test.s
看一看新编译的
2.png
3.png
可以看到已经成功实例化出一个模板函数,并链接。


总结:模板声明与实现都要放在同一文件内

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
Lucifer_BW + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-17 02:54

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表