zoukankan      html  css  js  c++  java
  • C++类模板

    在上篇文章(C++函数模板)中,主要介绍了C++中函数模板,与函数相似,类也可以被一种或多种类型参数化。容器类就是一个具有这种特性的典型的例子,

    本文地址:http://www.cnblogs.com/archimedes/p/cpp-class-template.html,转载请注明源地址。

    以下通过设计一个类模板Stack的实现来说明:

    类模板Stack的实现

    #include<iostream>
    #include<vector>
    #include<stdexcept>
    #include<string>
    #include<cstdlib>
    using namespace std;
    
    template<typename T>
    class Stack
    {
    private:
        vector<T> elems;  //存储元素的容器
    public:
        void push(T const&);  //压入元素
        void pop();           //弹出元素
        T top() const;        //返回栈顶元素
        bool empty() const {  //返回栈是否为空
            return elems.empty();
        }
    };
    
    template<typename T>
    void Stack<T>::push(T const& elem)
    {
        elems.push_back(elem);
    }
    
    template<typename T>
    void Stack<T>::pop()
    {
        if(elems.empty()) {
            throw out_of_range("Stack<>::pop(): empty stack");
        }
        elems.pop_back();
    }
    
    template<typename T>
    T Stack<T>::top() const
    {
        if(elems.empty()) {
            throw out_of_range("Stack<>::top(): empty stack");
        }
        return elems.back();
    }

    可以发现,类模板Stack<>是通过C++标准库vector<>来实现的,我们可以不需要亲自设计内存管理、拷贝构造函数和赋值运算

    类模板Stack的使用

    为了使用类模板对象,必须显式地指定模板实参,下面的例子展示了如何使用类模板Stack<>:

    int main()
    {
        try{
            Stack<int> intStack;
            Stack<string> stringStack;
    
            intStack.push(7);
            cout<<intStack.top()<<endl;
    
            stringStack.push("hello");
            cout<<stringStack.top()<<endl;
            stringStack.pop();
            stringStack.pop();
        }
        catch(exception const& ex) {
            cerr<<"Exception: "<<ex.what()<<endl;
            //return EXIT_FAILURE;
        }
        cin.get();  
        return 0;
    }

     通过声明类型Stack<int>,在类模板内部就可以用int实例化T。因此,intStack是一个创建自Stack<int>的对象,它的元素存储于vector,且类型为int,类似,如果声明和使用Stack<string>将会创建相应的对象。
    对于类模板,成员函数只有在被使用的时候才被实例化。

    显然,这样可以节省时间和空间,另一个好处是:对于那些“未能提供所有成员函数中所有操作的”类型,你可以使用该类型来实例化类模板,只要对那些“未能提供某些操作的”成员函数,模板内部不使用就可以。

    你可以像使用其他任何类型一样地使用实例化后的类模板类型(例如Stack<int>),只要它支持所调用的操作就可以:

    void foo(Stack<int> const& s)
    {
        Stack<int> istack[10];
        ...
    }

    借助于typedef,可以方便的使用类模板:

    typedef Stack<int> IntStack;
    void foo(IntStack const& s)
    {
        IntStack<int> istack[10];
        ...
    }

    类模板的特化
    可以使用模板实参来特化类模板,和函数模板的重载类似,通过特化类模板,你可以优化基于某种特定类型的实现,或者克服某种特定类型在实例化类模板时所出现的不足。

    为了特化一个类,你必须在起始处声明一个template<>,接下来声明用来特化类模板的类型:

    template<>
    class Stack<string> {
    private:
        deque<string> elems;
    public:
        void push(string const&);
        void pop();
        string top() const;
        bool empty() const {
            return elems.empty();
        }
    };
    
    void Stack<string>::push(string const& elem)
    {
        elems.push_back(elem);
    }
    
    void Stack<string>::pop()
    {
        if(elems.empty()) {
            out_of_range("Stack<string>::pop(): empty stack");
        }
        elems.pop_back();
    }
    
    string Stack<string>::top()
    {
        if(elems.empty()) {
            out_of_range("Stack<string>::top(): empty stack");
        }
        return elems.back();
    }
  • 相关阅读:
    解析大型.NET ERP系统 权限模块设计与实现
    Enterprise Solution 开源项目资源汇总 Visual Studio Online 源代码托管 企业管理软件开发框架
    解析大型.NET ERP系统 单据编码功能实现
    解析大型.NET ERP系统 单据标准(新增,修改,删除,复制,打印)功能程序设计
    Windows 10 部署Enterprise Solution 5.5
    解析大型.NET ERP系统 设计异常处理模块
    解析大型.NET ERP系统 业务逻辑设计与实现
    解析大型.NET ERP系统 多国语言实现
    Enterprise Solution 管理软件开发框架流程实战
    解析大型.NET ERP系统 数据审计功能
  • 原文地址:https://www.cnblogs.com/wuyudong/p/cpp-class-template.html
Copyright © 2011-2022 走看看