C++ primer 学习笔记- 16章(类模板)

1. 类模板

template <类型参数表>
class 类模板名{
成员函数和成员变量
};

1.1 实例化类模板

在这里插入图片描述
实例化场所:

-当使用了类模板实例的名字,并且上下文环境要求存在类的定义时
-对象类型是一个类模板实例,当对象被定义时。此点被称作类的实例化点
-一个指针或引用指向一个类模板实例,当检查这个指针或引用所指的对象时

1.2 类模板的成员函数

在类模板外定义

template <类型参数表>
返回值类型  类模板名<类型参数名列表>::成员函数名(参数表)
{
    ...
}

1.3 类模板和友元

  • 一对一
    BlobPtr 和 Blob
    BlobPtr 和 operator==
    Blob 和 operator==
#include <iostream>
#include <sstream>
using namespace std;

template <typename T> class  BlobPtr;
template <typename T> class  Blob;
template <typename T>
bool operator==(const Blob<T> &, const BlobPtr<T>&);

template <typename T> class  Blob
{
	friend class BlobPtr<T>;
	friend bool operator==<T>(const Blob<T>&, const BlobPtr<T>&);
private:
	int a;
public:
	Blob(T _a) :a(_a) {}
};

template <typename T> class  BlobPtr {
	friend bool operator==<T>(const Blob<T>&, const BlobPtr<T>&);
	int a;
public:
	BlobPtr(T _a) :a(_a) {}
};

template <typename T>
bool operator==(const Blob<T>& b, const BlobPtr<T>& bp)
{
	return b.a == bp.a ? true : false;
}
int main()
{
	Blob<int> b(1);
	BlobPtr<int> bp(1);
	std::cout << (b== bp) << endl;
}

在这里插入图片描述

template <typename T> class  Pal;
class C
{
	friend class Pal<C>; // C是所有是Pal<C>的友元
};

一对多:

template <typename T> class  Pal;
class C
{
	// Pal2 的所有实例都是C的友元,无需前置声明
	template <typename T> friend class  Pal2;
};

多对多

template <typename T>
class C2
{
	// Pal2 的所有实例都是C2每个实例的友元,无需前置声明
	template <typename T> friend class  Pal2;
}

1.4 类模板的static成员

template <typename T>
class Foo {
public:
    static std::size_t count() {
        return ctr;
    }
    void addctr() {
        ctr++;
    }
    void subctr() {
        ctr--;
    }
private:
    static std::size_t ctr;
    // 下面可以有其他成员接口
};

定义初始化

template <typename T>
std::size_t Foo<T>::ctr = 0;    //定义并初始化 ctr

每个 Foo 的实例都有自己的 static 成员实例。即,对任意给定类型X,都有一个Foo<X>::ctr 和一个 Foo<X>::count() 成员函数。所有 Foo<X>类型的对象共享相同的 ctr 对象和 count 函数

类似任何其他成员函数,一个static成员函数只有在使用的时候才会被实例化.

1.5 使用类的类型成员

(使用typename 表示T为一个类型)

template <typename T>
typename T::value_type top(const T& c)
{
}

1.6 默认模板实参

类模板(从右到左的规则):
编译OK

template <typename T, typename T2 = int> class  Pal; //编译OK

编译error (error C3747: 缺少默认 模板 参数: )

template <typename T =int, typename T= int> class  Pal; 

函数模板:

默认模板参数的位置则比较随意,但是推测的时候是从左往有的
// 没有函数匹配

template <typename T=int, typename U = int, typename U1  >
void f(T t = 0, U u = 0, U1 u1= 0) {};
f(1, 'c');

// 正常调用

template <typename T, typename U, typename U1=int  >
void f(T t = 0, U u = 0, U1 u1= 0) {};
f(1, 'c');

1.7 成员模板

1.7.1 普通类的成员模板

class DebugDelete
{
public:
    DebugDelete(std::ostream &s = std::cerr) os(s) { }
    //于任何模板相同,T的类型由编译器推断
    template <typename T> void operator()(T *p) const
    {
        os << "deleting unique_ptr" << std::endl;
        delete p;
    }
private:
    std::ostream &os;
};

1.7.2 类模板的成员模板

template <typename T>
class Blob
{
    template <typename It> Blob(It a, It b);
    //...
};
//在类模板外部进行其成员模板的函数体定义时,需要同时为类模板和成员模板提供模板参数列表。
template <typename T>
template <typename It>
Blob<T>::Blob(It a, It b) : data(std::make_shared<vector<T>>(a, b)) { }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值