zoukankan      html  css  js  c++  java
  • 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;  //int
    11         typedef T *iterator;   // int*->将int* 重定义为interator
    12         typedef const T* const_iterator;
    13         typedef T &reference; //int& -->将int& 重定义为reference
    14         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()const
    20         { return elems_; }
    21 
    22         iterator end()//end返回的是末尾元素的下个地址
    23         { return elems_+ MAXSIZE; }
    24         const_iterator end()const
    25         { return elems_+ MAXSIZE; }
    26 
    27         reference operator[](size_type index)//下标访问返回的是对本身的引用
    28         { return elems_[index]; }
    29         const_reference operator[](size_type index)const
    30         { 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的值,编译器会将其默认为NULL
    11         ~SmartPtr();
    12 
    13         T &operator*() //解引用操作返回的是本身值的引用
    14         { return *ptr_; }
    15         const T &operator*()const
    16         { return *ptr_; }
    17         
    18         T *operator->() //->操作 返回的是 指针本身;
    19         { return ptr_;}
    20         const T *operator->()const
    21         { 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 Stack
    11 {
    12     public:
    13         void push(const T &t);
    14         void pop();
    15         T top()const; 
    16 
    17         bool empty()const
    18         { 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     else
    35         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     else
    44         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()const
    58         { 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     else
    73         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     else
    81         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;
    }
  • 相关阅读:
    try catch finally
    类的小练习
    易混淆概念总结
    C#中struct和class的区别详解
    Doing Homework again
    悼念512汶川大地震遇难同胞——老人是真饿了
    Repair the Wall
    Saving HDU
    JAVA-JSP隐式对象
    JAVA-JSP动作
  • 原文地址:https://www.cnblogs.com/xfxu/p/4003740.html
Copyright © 2011-2022 走看看