C++学习笔记--数组类模板、智能指针模板、单例类模板

来源:互联网 发布:淘宝成交笔数对店铺 编辑:程序博客网 时间:2024/04/20 09:55

上一节中讲到类模板,本节就针对类模板常用的例子来强化类模板。

数组类模板

前面讲过类模板的泛指类型参数,在模板参数中除了类型参数还有一种数值型参数,数值型参数也有他自身的限制:

变量不能作为模板参数,什么意思呢?在声明了一个数值型参数后不能指定一个变量作为实际类型参数。

浮点数不能作为模板参数。

类对象不能作为模板参数。

本质上就是说数值型模板参数是在编译阶段被处理的单元,因此在编译阶段必须准确无误的唯一确定。

数组类是基于数值型模板参数实现的,它是简易的线性表数据结构。


实现一个高效的从1加到N:

template< int N >class Sum{public:    static const int VALUE = Sum<N-1>::VALUE + N;};template< >class Sum < 1 >{public:    static const int VALUE = 1;};
通过递归和数值型模板的方式实现加和,由于它是在编译期间就能确定下来所以它是十分高效。

调用方式:

Sum<10>::VALUE;//不能int a = 10;Sum<a>::VALUE;



下面实现一个简单的数组类模板:

#ifndef _ARRAY_H_#define _ARRAY_H_template< typename T, int N >class Array{    T m_array[N];public:    int length();    bool set(int index, T value);    bool get(int index, T& value);    T& operator[] (int index);    T operator[] (int index) const;    virtual ~Array();};template< typename T, int N >int Array<T, N>::length(){    return N;}template< typename T, int N >bool Array<T, N>::set(int index, T value){    bool ret = (0 <= index) && (index < N);        if( ret )    {        m_array[index] = value;    }        return ret;}template< typename T, int N >bool Array<T, N>::get(int index, T& value){    bool ret = (0 <= index) && (index < N);        if( ret )    {        value = m_array[index];    }        return ret;}template< typename T, int N >T& Array<T, N>::operator[] (int index){    return m_array[index];}template< typename T, int N >T Array<T, N>::operator[] (int index) const{    return m_array[index];}template< typename T, int N >Array<T, N>::~Array(){}#endif


创建一个数组:

Array<double, 5> ad;//double类型的五个元素的数组


智能指针模板

我们需要的智能指针模板是自动内存管理的主要手段,它防止内存泄漏和多次释放 同一片空间,生命周期结束时销毁指向的内存空间,不能指向堆数组,只能指向堆对象,多个智能指针对象不能指向同一片堆空间,很大程度上避开内存相关BUG。


实现一个简单的智能指针模板:

#ifndef _SMARTPOINTER_H_#define _SMARTPOINTER_H_template< typename T >class SmartPointer{    T* mp;public:    SmartPointer(T* p = NULL)    {        mp = p;    }        SmartPointer(const SmartPointer<T>& obj)    {        mp = obj.mp;        const_cast<SmartPointer<T>&>(obj).mp = NULL;    }        SmartPointer<T>& operator = (const SmartPointer<T>& obj)    {        if( this != &obj )        {            delete mp;            mp = obj.mp;            const_cast<SmartPointer<T>&>(obj).mp = NULL;        }                return *this;    }        T* operator -> ()    {        return mp;    }        T& operator * ()    {        return *mp;    }        bool isNull()    {        return (mp == NULL);    }        T* get()    {        return mp;    }        ~SmartPointer()    {        delete mp;    }};#endif


单例类模板

单例类模板的需求就是只有一个对象存在,要实现这个要求我们只能对外隐藏构造函数(构造和拷贝构造)。

有这么一个思路:

将构造函数属性设置为private。

定义一个指针作为标识符,如果为NULL则创建对象并返回,否则返回已有的对象。

将指针标识符作为static类型,再加一个static成员函数,这样才能在为创建对象时调用。


首先建立一个单例类模板:

template<typename T>class Singleton{private:    static T *c_instance;public:    static T* GetInstance();};template<typename T>T* Singleton<T> :: c_instance = NULL;template<typename T>T* Singleton<T>::GetInstance(){    if(c_instance == NULL)    {        c_instance = new T();    }    return c_instance;}


在具体要实现单例的类中将单例类模板声明为友元类,举一个例子:

class Sobject{private:    friend class Singleton<Sobject>;//当前类需要使用单例模式    Sobject& operator= (const Sobject& obj){  }    Sobject(){  }    Sobject(const Sobject& obj){  }public:    void print(){  cout << "this = " << this << endl;  }};


我们想在Sobject类中实现只能创建一个对象,首先将构造函数隐藏,再使用友元类创建对象:

    Sobject *p1 = Singleton<Sobject> :: GetInstance();    Sobject *p2 = Singleton<Sobject> :: GetInstance();    Sobject *p3 = Singleton<Sobject> :: GetInstance();    p1->print();    p2->print();    p3->print();
打印结果;

this = 0x2254070
this = 0x2254070
this = 0x2254070
表示三个类对象指向同一个地址。