C++57个入门知识点_56 类模板(类模板定义:对某一个类型进行变量的替换,类模板放在.h文件中;类模板只能显式实例化;类模板在类内及类外的写法;类模板的函数特例)

上篇C++57个入门知识点_55 函数模板(template<typename T>;T GetMin(T a, T b){};函数模板定义;隐式实例化;显式实例化;函数模板特例;实例化后模板才有效)介绍了函数模板的相关概念,本篇将介绍C++中长用到另一种模板-类模板。

总结:

1.类模板的定义:

  • 对某一个类型进行变量的替换
  • 类模板放在.h文件中

2.类模板的显式实例化: 类模板中是无法使用隐式实例化,只能使用显示实例化
3.类模板的写法:

  • 类模板写在类内
  • 类模板写在类外

4.类模板的函数特例

1. 类模板的定义


类模板顾名思义即把类作为一个模板

类模板:

  • 对某一个类型进行变量的替换
  • 类模板放在.h文件中

以下CTest类中定义返回为对象的函数

#include <iostream>

class CTest {

public:
	CTest& foo(CTest& obj) {
		return *this;
	}

private:
	int m_nInt;

};

int main(int argc, char* argv[])
{
	CTest t;

	return 0;
}

在类模板中,将上面成员变量int m_nInt;int看做一个变量,假设用T来表示,则对应类模板的定义方法有如下两种:
(1)使用class关键字

#include <iostream>

template <class T>
class CTest {

public:
	CTest& foo(CTest& obj) {
		return *this;
	}

private:
	T m_nInt;

};

int main(int argc, char* argv[])
{
	CTest <int> t;

	return 0;
}

(2)使用typename关键字
一般而言不建议使用上述class关键字的方式,其可能有类的关键字class冲突,而使用函数模板中使用的typename关键字。

#include <iostream>

template <typename T>
class CTest {

public:
	CTest& foo(CTest& obj) {
		return *this;
	}

private:
	T m_nInt;

};

int main(int argc, char* argv[])
{
	CTest <int> t;

	return 0;
}

2. 类模板的显式实例化


类模板中是无法使用隐式实例化,只能使用显示实例化,因为使用隐式实例化是无法找到对应的数据类型的。除了上述的写法,还可以使用以 下多个参数和常量赋值的形式。

书写方法:显式实例化CTest<int, double, 7> t中template关键字被对应的类CTest替换,<int, double, 7> 为对应的数据类型

#include <iostream>

template<typename T, typename K = double, int n = 5>
class CTest {

public:
	//写于类域内部
	CTest& foo(CTest& obj) {
		return *this;
	}
private:
	T m_nInt;
	K m_nDouble;
	int m = n;
};

int main(int argc, char* argv[])
{
	//只能通过显式实例化使编译器猜对使用的类型
	CTest<int, double, 7> t;

	return 0;
}

运行结果:多个数据类型,对常量进行初始化
在这里插入图片描述

3. 类模板的写法

3.1 类模板写在类内


一般而言 ,类模板是放在.h文件中,类模板别人再用的时候是不希望编译的,放在 .cpp中是不太好,它不能对 .cpp产生对应的 obj文件,不能编译。

具体写法如下:

  • .h
#pragma once
//类模板
//对某一个类型进行变量的替换
//类模板放在.h文件中

//类模板的定义格式如下:
//支持多个及默认参操作
//template模板关键字、<typename T, typename K = double, int n = 5>类中包含的数据类型
//class CTest {}为类定义,其中T,K作为数据类型使用,类似于Int,double等,不好懂时用Int等代替理解
template<typename T, typename K = double, int n = 5>
class CTest {

public:
//写于类域内部
	CTest& foo(CTest& obj) {
		return *this;
	}
private:
	T m_nInt;
	K m_nDouble;
	int m = n;
};
  • .cpp

#include <iostream>
#include"testCPP.h"

int main(int argc,char* argv[])
{
	//只能通过显式实例化使编译器猜对使用的类型
	CTest<int,double,7> t;
	return 0;
}

3.2 类模板写在类外


类模板的函数体可以写在类内,也可以利用四饼连接符写在类外,上为写在类内,下为写在类外的形式。
我们知道,把函数写在类里面是函数内联,但有时候我们需要将函数声明和实现分开。可以通过以下的写法实现。

  • .h
#pragma once
template<typename T>
class CTest {

public:
	//写于类域内部
	CTest& foo(CTest& obj);
private:
	T m_nInt;
};

//写于类域外部的标准写法
template<typename T>
CTest<T>& CTest<T>::foo(CTest<T>& obj) {
	T obj2;
	return *this;
}
  • .cpp
#include <iostream>
#include "testCPP.h"

int main(int argc, char* argv[])
{
	//只能通过显式实例化使编译器猜对使用的类型
	CTest<int> t;

	return 0;
}

4. 类模板的函数特例


有时候,类模板内的函数也需要特例时可以如下去写:

  • .h
#pragma once
template<typename T>
class CTest {

public:
	//写于类域内部
	CTest& foo(CTest& obj);

	T get();

private:
	T m_nInt;
};

//写于类域外部的标准写法
template<typename T>
CTest<T>& CTest<T>::foo(CTest<T>& obj) {
	T obj2;
	return *this;
}

//普通类模板成员函数
template<typename T>
T CTest<T>::get() {

	return m_nInt;
}

//类模板成员函数特例
template<>
const char* CTest<const char*>::get() {

	return "Hello";
}
  • .cpp
#include <iostream>
#include "testCPP.h"

int main(int argc, char* argv[])
{
	//类模板成员函数特例
	CTest<char*> t;

	char* p = t.get();

	//非特例
	CTest<int> t2;

	int n = t2.get();

	return 0;
}

5.学习视频地址:C++57个入门知识点_56 类模板

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十月旧城

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值