C++中类模板(class template) 详解

类模板(class template)需要添加模板参数(template parameter), 即最前面添加"template <template T>";

把所有需要使用模板类型的位置, 使用"T"代替; 使用时需要填加"Class<T>",指定模板参数;

在定义类的成员函数(member function)时, 也需要添加类的模板参数"template <template T>",

并且在声明函数的归属类时, 类需要转换为模板类, 即"Class::"转换为"Class<T>::";

如果在类中, 如果使用本类对象, 即当前对象, 则可以不添加模板参数(添加也不没有问题);

其余注意初始化列表"initializer_list"的用法, 和前缀++或--与后缀++或--在重载时的区别;

代码如下:

/*
 * cppprimer.cpp
 *
 *  Created on: 2013.11.21
 *      Author: Caroline
 */

/*eclipse cdt, gcc 4.8.1*/

#include <iostream>
#include <vector>
#include <initializer_list>
#include <memory>
#include <cstddef>  

template <typename T> class BlobPtr;
template <typename T> class Blob;  

/*Blob: Binary Large OBject*/
template <typename T> class Blob {
    friend class BlobPtr<T>;
public:
    typedef T value_type;
    typedef typename std::vector<T>::size_type size_type;
    Blob ();
    Blob (std::initializer_list<T> il); //可以使用初始化列表, {}
    size_type size() const { return data->size(); }
    bool empty() const { return data->empty(); }
    void push_back (const T &t) { data->push_back(t); }
    void push_back (T &&t) { data->push_back(std::move(t)); } //右值操作
    void pop_back ();
    T& back ();
    T& operator[] (size_type i) ;
private:
    std::shared_ptr<std::vector<T> > data;
    void check (size_type i, const std::string &msg) const; //验证给定的索引
};  

template <typename T>
Blob<T>::Blob () : data(std::make_shared<std::vector<T>>()) {}  

template <typename T>
Blob<T>::Blob (std::initializer_list<T> il) :
        data(std::make_shared< std::vector<T> >(il)) {}  

/*验证给定的索引*/
template <typename T>
void Blob<T>::check (size_type i, const std::string &msg) const
{
    if (i >= data->size())
        throw std::out_of_range (msg); //抛出异常
}  

template <typename T>
T& Blob<T>::back ()
{
    check (0, "back on empty Blob");
    return data->back ();
}  

template <typename T>
T& Blob<T>::operator[] (size_type i)
{
    check (i, "subscript out of range");
    return (*data)[i];
}  

template <typename T>
void Blob<T>::pop_back ()
{
    check (0, "pop_back on empty Blob");
    data->pob_back ();
}  

template <typename T>
class BlobPtr {
public:
    BlobPtr () : curr (0) {}
    BlobPtr (Blob<T> &a, size_t sz=0) : wptr(a.data), curr (sz) {}
    T& operator* () const {
        auto p = check (curr, "dereference past end");
        return (*p) [curr];
    }
    BlobPtr& operator++ (); //前缀操作符
    BlobPtr& operator-- ();
    BlobPtr operator++ (int); //后缀操作符
    BlobPtr operator-- (int);
private:
    std::shared_ptr<std::vector<T>> check (std::size_t, const std::string&) const;
    std::weak_ptr<std::vector<T>> wptr;
    std::size_t curr;
};  

template <typename T>
std::shared_ptr<std::vector<T>>
BlobPtr<T>::check (std::size_t i, const std::string& msg) const
{
    auto ret = wptr.lock (); //判断wptr是否绑定了Blob
    if (!ret)
        throw std::runtime_error ("unbound BlobPtr");
    if (i >= ret->size ())
        throw std::out_of_range (msg);
    return ret;
}  

template <typename T>
BlobPtr<T>& BlobPtr<T>::operator++ () {
    check (curr, "increment past end of BlobPtr"); //先判断后加
    ++curr;
    return *this;
}  

template <typename T>
BlobPtr<T>& BlobPtr<T>::operator-- () {
    --curr; //先减之后, 如果为0, 再减就是大整数
    check (curr, "decrement past begin of BlobPtr"); //先减后判断
    return *this;
}  

template <typename T>
BlobPtr<T> BlobPtr<T>::operator ++(int)
{
    BlobPtr ret = *this;
    ++*this; //使用重载的前缀++
    return ret;
}  

template <typename T>
BlobPtr<T> BlobPtr<T>::operator --(int)
{
    BlobPtr ret = *this;
    --*this; //使用重载的前缀--
    return ret;
}  

int main (void) {
    std::cout << "Hello Mystra!" << std::endl;
    Blob<int> ia;
    Blob<int> ia2 = {0, 1, 2, 3, 4};
    std::cout << "ia2[2] = " << ia2[2] << std::endl;
    BlobPtr<int> pia = ia2;
    std::cout << "*(++pia) = " << *(++pia) << std::endl;
    return 0;
}

作者:csdn博客 Spike_King

更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/cplus/

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索blob
, return
, const
, template
, c++ push_back
, std::move
, initializer_list
, std
, operator
, Blob类型详解
weak_ptr
arttemplate模板引擎、js template 模板引擎、stringtemplate 模板、template模板、template模板 语法 js,以便于您获取更多的相关知识。

时间: 2024-09-02 13:34:56

C++中类模板(class template) 详解的相关文章

C++中函数模板(function template) 详解

C++的模板(template)是泛型编程(generic programming)的基础; 面向对象编程 是 运行(run time)时 知道类型(type); 泛型编程 是编译(compilation) 知道类型; 函数模板(function template)包含模板参数列表(template parameter list); 每个参数类型之前必须包含关键字typename或class, 尽量使用typename, 表达意思更加明确; 非类型模板参数(Nontype Template Pa

Android开发之Android.mk模板的实例详解

Android开发之Android.mk模板的实例详解 关于Android NDK开发的文章已经比较多了,我的博客中也分享了很多NDK开发相关经验和技巧,今天简单写了一个 Android.mk 的示例模板,供初学者参考. 本模板主要给大家示例 Android NDK 开发中的如下几个问题: 1. 如何自动添加需要编译的源文件列表   2. 如何添加第三方静态库.动态库的依赖   3. 如何构造一个完整的NDK工程框架 假设我们的项目依赖 libmath.a, libjson.a, libffmp

Python语言:定制语法的string模板(template) 详解

string.Template()内添加替换的字符, 使用"$"符号, 或 在字符串内, 使用"${}"; 调用时使用string.substitute(dict)函数. 可以通过继承"string.Template", 覆盖变量delimiter(定界符)和idpattern(替换格式), 定制不同形式的模板. 代码: # -*- coding: utf-8 -*- ''''' Created on 2014.6.5 @author: Admi

Python语言:定制pattern的string模板(template) 详解

string.Template的pattern是一个正则表达式, 可以通过覆盖pattern属性, 定义新的正则表达式. 如: 使用新的定界符"{{", 把{{var}}作为变量语法. 代码: # -*- coding: utf-8 -*- ''''' Created on 2014.6.5 @author: Administrator @edition : python 3.3.0, eclipse pydev ''' import string t = string.Templat

C++中成员函数(member function)模板(template) 详解

成员模板(member template) 既可以在普通类(ordinary class), 也可以在类模板(class template); 在普通类中, 在使用成员函数时, 不用提供模板参数, 函数可以根据使用的参数, 自动推导(deduce)模板实参(template argument)对应模板形参(template parameter); 在类模板中, 成员函数的模板参数(template parameter)可以和类的模板参数不同, 但在定义(definition)中, 必须添加两个模

C++类模板与模板类深入详解_C 语言

1.在c++的Template中很多地方都用到了typename与class这两个关键字,而且有时候二者可以替换,那么是不是这两个关键字完全一样呢? 事实上class用于定义类,在模板引入c++后,最初定义模板的方法为:template<class T>,这里class关键字表明T是一个类型,后来为了避免class在这两个地方的使用可能给人带来混淆,所以引入了typename这个关键字,它的作用同class一样表明后面的符号为一个类型,这样在定义模板的时候就可以使用下面的方式了:      t

javascript中类的定义方式详解(四种方式)_javascript技巧

本文实例讲述了javascript中类的定义方式.分享给大家供大家参考,具体如下: 类的定义包括四种方式: 1.工厂方式 function createCar(name,color,price){ var tempcar=new Object; tempcar.name=name; tempcar.color=color; tempcar.price=price; tempcar.getName=function(){ document.write(this.name+"-----"+

C++中类模板(class template)友元(friend) 的全部六种形式

类模板(class template)的友元(friend)和普通类的友元, 有很多区别, 主要原因是类模板包含模板参数(template parameter), 就会导致友元和类模板有很多匹配形式; 主要包含六种形式: 1. 类 - 友元(friend): "模板参数是当前类"的类模板; 2. 类 - 友元: "模板参数任意"的模板类; 3. 模板类 - 友元: "模板参数相同"的模板类; 4. 模板类 - 友元: "模板参数任意&q

php Smarty 模板使用方法详解

一.模板中的注释 每一个Smarty模板文件,都是通过Web前台语言(xhtml,css和javascript等)结合Smarty引擎的语法开发的.  用到的web前台开发的语言和原来的完全一样,注释也没有变化       Smarty注释语法是'左结束符变量值*'和'*右结束符变量值',在这两个定界符之间的内容都是注释内容,可以包含一行或多行,并且用户浏览网页查看原代码时不会看到注释,它只是模板内在的注释,以下是注释小例子.     $smarty->left_lelimiter = '<{