首页 > 代码库 > C++学习之模板应用 ---array、smartptr、stack

C++学习之模板应用 ---array、smartptr、stack

有array(数组)、smartptr(智能指针)、stack(栈);

一、array:

1、我们实现了指针访问和下标访问。C++中指针访问常用迭代器来代替。

2、这里我们也揭示了 size_type、iterator、[] 、begin()、end()、size()的真实面目;

Array.hpp

 1 #ifndef ARRAY_H_ 2 #define ARRAY_H_ 3 //Arrar.hpp 4 #include <stddef.h> 5 template <typename T, int MAXSIZE> 6 class Array 7 { 8     public: 9         //我们假设T为int型10         typedef T value_type;  //int11         typedef T *iterator;   // int*->将int* 重定义为interator12         typedef const T* const_iterator;13         typedef T &reference; //int& -->将int& 重定义为reference14         typedef const T& const_reference;15         typedef size_t size_type;//size_type常用于vector<int>::size_type 下表访问16  17         iterator begin()//begin返回的是首地址18         { return elems_; }19         const_iterator begin()const20         { return elems_; }21 22         iterator end()//end返回的是末尾元素的下个地址23         { return elems_+ MAXSIZE; }24         const_iterator end()const25         { return elems_+ MAXSIZE; }26 27         reference operator[](size_type index)//下标访问返回的是对本身的引用28         { return elems_[index]; }29         const_reference operator[](size_type index)const30         { return elems_[index]; }31 32         size_type size()const  //int->元素个数33         { return MAXSIZE;}34     private:35         T elems_[MAXSIZE];36 };37 
38 #endif

main.cpp:

 1 #include "Array.hpp" 2 #include <iostream> 3 #include <algorithm> 4 using namespace std; 5  6 template <typename T> 7 void print(const T &t) 8 { 9     for(typename T::const_iterator it = t.begin(); //迭代器实现打印10          it!= t.end();11          it++)12     {13         cout << *it << " ";14     }15     cout << endl;16 }17 18 int main(int argc, const char *argv[])19 {20     Array<int, 20> arr;21 22     for(Array<int, 20>::size_type ix =0;   //下标实现初始化23         ix != arr.size();24         ix ++)25     {26         arr[ix] = ix;27     }28     29     print(arr);30     31     Array<int, 20>::const_iterator it=std::find(arr.begin(), arr.end(), 15);32     cout << *it << endl; //标准库中的find函数33 34     return 0;35 }

 

二、智能指针:
这里我们实现了指针的一些操作, 如解引用操作符,->操作符、指针的复制与赋值。

代码如下:

SmartPtr.hpp

 1 #ifndef SMARTPTR_H_ 2 #define SMARTPTR_H_ 3  4 #include <stddef.h> 5  6 template <typename T> 7 class SmartPtr 8 { 9     public:10         SmartPtr(T *ptr= NULL ); //如果没有提供ptr的值,编译器会将其默认为NULL11         ~SmartPtr();12 13         T &operator*() //解引用操作返回的是本身值的引用14         { return *ptr_; }15         const T &operator*()const16         { return *ptr_; }17         18         T *operator->() //->操作 返回的是 指针本身;19         { return ptr_;}20         const T *operator->()const21         { return ptr_;}22 23         void resetPtr(T *ptr = NULL); //将 指针重置24         const T *getPtr()const //获取该指针25         { return ptr_; }26 27     private:28         //这里我们禁用了智能指针的复制和赋值能力29         SmartPtr(const SmartPtr&); 30         SmartPtr &operator=(const SmartPtr&);31 32         T *ptr_;  33 };34 35 template <typename T>36 SmartPtr<T>::SmartPtr(T *ptr )37     :ptr_(ptr)38 { }39 40 template <typename T>41 SmartPtr<T>::~SmartPtr()42 { delete ptr_; } 43 44 template <typename T>45 void SmartPtr<T>::resetPtr(T *ptr )46 {47     if(ptr_ == ptr) //如果把自己本身赋值给自己,则直接返回48         return;49     delete ptr_;50     ptr_ = ptr ;51 }52 53 #endif

main.cpp:

 1 #include "SmartPtr.hpp" 2 #include <iostream> 3 using namespace std; 4  5 class Test 6 { 7     public: 8  9         Test() {cout << "construct" << endl; }10         ~Test(){cout << "~construct" << endl; }11 };12 13 int main(int argc, const char *argv[])14 {15     SmartPtr<Test> sp(new Test); 16 17     return 0;18 }


三、Stack 及其特化:

1、这里我们揭示了Stack 的 pop、push、top、empty操作;

2、对于一些特殊的类型,如 const char*(C风格的字符串),当我们用push函数时,总会出现一些问题,原因在于:

push函数复制给定值以创建 stack中的新元素(值拷贝),而默认情况下,复制C 风格字符串只会复制其指针,不会复制字符串(衰退【decay】),这时复制指针将会出现共享指针在其他环境中会出现的所有问题(如重复析构),最严重的是,若指针指向动态内存,用户就有可能删除指针所指的数组。

 1 //Stack.hpp 2 #ifndef STACK_H_ 3 #define STACK_H_ 4  5 #include <vector> 6 #include <stdexcept> 7  8 //Stack----------------------- 9 template <typename T>10 class Stack11 {12     public:13         void push(const T &t);14         void pop();15         T top()const; 16 17         bool empty()const18         { return elems_.empty(); }19     private:20         std::vector<T> elems_;21 };22 23 template <typename T>24 void Stack<T>::push(const T &t)25 {26     elems_.push_back(t);27 }28 29 template <typename T>30 void Stack<T>::pop()31 {32     if( !elems_.empty() )33         elems_.pop_back();34     else35         throw std::out_of_range("out of range");36 }37 38 template <typename T>39 T Stack<T>::top()const 40 {41     if( !elems_.empty() )42         return elems_.back();43     else44         throw std::out_of_range("out of range");45 }46 //----------------------------47 48 //特化------------------49 template <>50 class Stack<const char*>51 {52     public:53         void push(const char *);54         void pop();55         const std::string top()const;  56        //注意上面的函数返回的是string,为了避免管理字符数组char[]57         bool empty()const58         { return elems_.empty(); }59     private:60         std::vector<std::string> elems_; //通过这一数据元素实现以上各个功能61 };62 63 void Stack<const char*>::push(const char*t)64 {65     elems_.push_back(t);66 }67 68 void Stack<const char*>::pop()69 {70     if( !elems_.empty() )71         elems_.pop_back();72     else73         throw std::out_of_range("out of range");74 }75 76 const std::string Stack<const char*>::top()const 77 {78     if( !elems_.empty() )79         return elems_.back();80     else81         throw std::out_of_range("out of range");82 }83 //----------------84 85 #endif

 

main.cpp

//main.cpp#include "Stack.hpp"#include <iostream>using namespace std;int main(int argc, const char *argv[]){    try    {        const char *s1 = "foo";        Stack<const char *> st;                st.push(s1);        st.push("bar");                cout << st.top() << endl;        st.pop();        cout << st.top() << endl;        st.pop();    }    catch(exception &e)    {        cout << e.what()<< endl;    }    return 0;}

 

C++学习之模板应用 ---array、smartptr、stack