首页 > 代码库 > 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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。