C++模板与泛型 --- 成员函数模板,显式实例化、声明
2019-05-15 本文已影响11人
307656af5a04
上一节我们学习了typename的使用场合、默认模板参数、趣味写法分析,通过上一节的学习,大家对typename的使用场合、默认模板参数、趣味写法分析有一个比较清晰的认识,那么本节,我们继续学习模板与泛型的知识,即t成员函数模板,显示实例化、声明,希望通过本节的学习,大家能够对模板与泛型的概念有一个更加清晰的认识!
一、普通类的成员函数模板
不管是普通类,还是模板类,它的成员函数可以是一个函数模板,称为"成员函数模板",但是这个函数不可以是虚函数,否则,编译器会报错。
class A // 普通类
{
public:
template <typename T>
// 成员函数模板
void myft(T tmpt)
{
cout << tmpt << endl;
}
};
int main()
{
A a;
// 编译器在遇到这条语句时,
// 编译器就会实例化这个函数模板
a.myft(3);
}
二、类模板的成员函数模板
类模板的模板参数必须用<>指定,成员函数模板、普通函数模板的参数都可以推断出来;
类模板的成员函数(包括普通成员函数/成员函数模板)只有为程序所用,才会实例化;如果函数从未使用,则不会实例化该成员函数。
#include <iostream>
using namespace std;
// 类模板的参数
template <typename C>
class A // 普通类
{
public:
// 构造函数模板
// 与整个类的模板没有关系
template <typename T2>
A(T2 v1, T2 v2);
template <typename T>
// 成员函数模板
void myft(T tmpt)
{
cout << tmpt << endl;
}
// 普通成员函数
void myfun(){ }
C m_ic; // 类模板变量
};
// 先跟类的模板参数列表
template <typename C>
// 再跟构造函数自己的模板参数列表
template <typename T2>
A<C>::A(T2 v1, T2 v2)
{
cout << v1 << v2 << endl;
}
int main()
{
A<float> a(1, 2);
A<float> b(1.1, 2.2);
return 0;
}
三、模板显式实例化,模板声明
为了防止多个.cpp文件中都实例化相同的类模板,所以C++11提出了一个解决方法,我们称为"显式实例化";通过"显式实例化"避免生成多个相同类模板实例的开销。
模板的实例化定义只有一个,模板的实例化声明可以有多个。
实例
ca.h
#pragma once
#ifndef __CAH__
#define __CAH__
#include <iostream>
// 类模板的参数
template <typename C>
class A // 普通类
{
public:
// 构造函数模板
// 与整个类的模板没有关系
template <typename T2>
A(T2 v1, T2 v2);
template <typename T>
// 成员函数模板
void myft(T tmpt)
{
cout << tmpt << endl;
}
// 普通成员函数
template <typename T2>
void myfunc(T2 v1, T2 v2);
C m_ic; // 类模板变量
};
// 先跟类的模板参数列表
template <typename C>
// 再跟构造函数自己的模板参数列表
template <typename T2>
A<C>::A(T2 v1, T2 v2)
{
cout << v1 << v2 << endl;
}
template <typename T>
void mfunc123(T v1, T v2)
{
cout << v1 + v2 << endl;
}
#endif
ca.cpp
#include "ca.h"
using namespace std;
// 显式实例化手段中的实例化定义,这种实例化只需在一个.cpp
// 文件中写就可以
// 编译器遇到这段代码就直接实例化一个A<float>
template A<float>;
void mfunc()
{
A<float> a(1, 2);
}
// 先跟类的模板参数列表
template <typename C>
// 再跟构造函数自己的模板参数列表
template <typename T2>
void A<C>::myfunc(T2 v1, T2 v2)
{
}
// 编译器会为其生成代码
template void mfunc123(int v1, int v2);
main.cpp
#include <iostream>
#include "ca.h"
using namespace std;
// 显式实例化手段中的"实例化声明"
// 其他所有.cpp文件用到这个类型的话都这么写
// 在一个文件中实例化,其他文件全部为声明
// extern template A<float>;
// extern作用:不会在在本文件中生成一个extern后面所表示的模板的实例化代码
// extern目的:告诉编译器,在其他的源文件(.cpp)中已经有了一个改该模板的实例化版本了。
extern template A<float>;
// 显式声明函数模板
extern template void mfunc123(int v1, int v2);
int main()
{
A<float> a(1, 2);
A<float> b(1.1, 2.2);
return 0;
}
我是奕双,现在已经毕业将近两年了,从大学开始学编程,期间学习了C需要编程,C++需要编程,Win32编程,MFC编程,毕业之后进入一家图像处理相关领域的公司,掌握了用OpenCV对图像进行处理,如果大家对相关领域感兴趣的话,可以关注我,我这边会为大家进行解答哦!如果大家需要相关学习资料的话,可以私聊我哦!