C++模版技术
void MySwap(T& a,T& b)//两数交换函数
{
int temp = a;
a = b;
b = temp;
}
模版函数能进行自动类型推导,会根据数据类型自动推导函数的数据类型。
void test()//自动类型推导
{
int a = 10;
int b = 20;
MySwap(a,b);//编译器根据你传递过来的值,进行自动类型推导。
}
//显式的指定类型
MySwap<int>(a,b);
模版函数和普通函数的区别–函数模版不允许自动类型转换
函数模版和普通p函数一起调用的规则:
-
模版函数可以像普通函数那样被重载。 -
C++编译器优先考虑普通函数。 -
如果模版函数可以产生一个更好的匹配,那么选择模版函数。 -
可以通过空模版实参列表的语法限定编译器只能通过模版匹配。
例:MyAdd<>(a,b );//强制使用模版函数。
函数模版机制结论:
-
编译器并不是把函数模板处理成任何类型的函数。 -
函数模板通过具体的类型产生不同的模版函数。 -
编译器会对函数模版进行两次编译,在声明的地方对函数模版本身进行编译,在调用的地方对参数替换后的代码进行编译。
类模版
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
template<class T>//不唯一
class Person {
public:
Person(T id, T age) {
this->mAge = age;
this->mID = id;
}
void Show()
{
cout << "ID" << mID << "Age" << mAge << endl;
}
public:
T mID;
T mAge;
};
void test01()
{
//函数模板在调用的时候,可以自动类型推导
//类模版必须显式制定类型
Person<int>p(10,20);
p.Show();
}
int main(void)
{
test01();
return 0;
}
模板类派生普通类
- 模板类派生普通类时,必须要声明类型!
- 模板类派生时,需要具体化模板类,因为C++编译器需要知道,父类的数据类型具体时什么样子的,才可以分配内存——即要知道父类所占内存大小是多少,只有数据类型固定下来,才知道如何分配内存。
示例:
template<class T>
class Person
{
public:
Person()
{
mage = 0;
}
private:
T mage;
};
class sonPerson : public Person<int> //这里不加<int>,会生成失败
{ };
类模板派生模板类
模板类派生模板类时,可以不声明类型!
这样写就是正确的!为什么呢?
template<class T>
class Person
{
public:
Person()
{
mage = 0;
}
private:
T mage;
};
template<class T>
class SonPerson2:public Person<T>
{
public:
SonPerson2() {};
SonPerson2() {};
private:
};
原因是在调用这个被派生的模板类时,我们需要先声明类型,所以此时编译器知道如何申请内存
分离式编译模式
Person.h(头文件中只写类的声明)
#pragma once//防止头文件重复包含
#include<iostream>
#include<string>
using namespace std;
class Person {
public:
Person(string name, int age);
void Show();
public:
string mName;
int mAge;
int mID;
};
//Person.cpp(写类的具体实现)
\#include"Person.h"
Person::Person(string name, int age)
{
this->mName = name;
this->mAge = age;
}
void Person::Show() {
cout << "Name" << " " << this->mName << " " << "Age" << " " << this->mAge << endl;
}
//main.cpp(类的实例化)
\#define _CRT_SECURE_NO_WARNINGS
\#include<iostream>
using namespace std;
\#include"Person.h"
int main(void)
{
Person p("AAA", 20);
p.Show();
return 0;
}
类模版在类内实现
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;
template<class T1,class T2>
class Person {
public:
Person(T1 name, T2 age) {
this->mName=name;
this->mAge = age;
}
void Show() {
cout << "Name" << this->mName << "Age" << this->mAge << endl;
}
public:
T1 mName;
T2 mAge;
};
void test01()
{
Person<string, int>p("AAA", 20);
p.Show();
}
int main(void)
{
test01();
return 0;
}
类模版遇到static成员
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
template<class T>
class Person{
public :
static int a;
};
//类外初始化
template<class T> int Person<T>::a = 0;
int main(void)
{
Person<int> p1, p2, p3;
Person<char>pp1, pp2, pp3;
p1.a = 10;
pp1.a = 100;
cout << p1.a << " " << p2.a << " " << p3.a << endl;
cout << pp1.a << " " << pp2.a << " " << pp3.a << endl;
//若p1 p2 p3 和,pp1 pp2 pp3共享一个static成员的话,输出的这六个值应该相同
// 每个生成的具体的类,共享自己的static成员
return 0;
}
|