• C++模板


    在GameBoard,h文件:

    #ifndef _GAMEBOARD_H
    #define _GAMEBOARD_H
    #include <iostream>
    #include <vector>
    template<typename T>
    class GameBoard
    {
        public:
            GameBoard();
            GameBoard(const T& src);    //复制构造函数
            GameBoard(size_t inWidth,size_t inHeight);
            virtual ~GameBoard();
            
        public:
            void setElemAt(size_t x,size_t y,const T& inElem);
            const T& getElem(size_t x,size_t y);
            size_t getWidth(){return mWidth;}
            size_t getHeight(){return mHeight;}
            static const size_t mDefaultWidth = 10;
            static const size_t mDefaultHeight = 10;        
            
        private:    
            size_t mWidth,mHeight;
            void copyFrom(const T& src);
            void initialContainer();
            std::vector<std::vector<T>> mCells;
    };
    
    
    
    
    
    
    
    #endif //_GAMEBOARD_H

    在GameBoard.cpp文件里:

    #include "GameBoard.h"
    
    template<typename T>
    GameBoard<T>::GameBoard()
    :mWidth(0)
    ,mHeight(0)
    {
        initialContainer();
    }
    template<typename T>
    GameBoard<T>::GameBoard(const T& src)
    :mWidth(src.mWidth)
    ,mHeight(src.mHeight)
    {
        copyFrom(src);
    }
    template<typename T>
    GameBoard<T>::GameBoard(size_t inWidth,size_t inHeight)
    :mWidth(inWidth > mDefaultWidth ? mDefaultWidth : inWidth)
    ,mHeight(inHeight > mDefaultHeight ? mDefaultHeight : inHeight)
    {
        initialContainer();
    }
    template<typename T>
    GameBoard<T>::~GameBoard()
    {
        
    }
    template<typename T>
    void GameBoard<T>::setElemAt(size_t x,size_t y,const T& inElem)
    {
        mCells[x][y] = inElem;
    }
    template<typename T>
    const T& GameBoard<T>::getElem(size_t x,size_t y)
    {
        return mCells[x][y];        
    }
    template<typename T>
    void GameBoard<T>::copyFrom(const T& src)
    {
        mWidth = src.mWidth;
        mHeight = src.mHeight;
        initialContainer();
        
        for(int i = 0;i < mWidth;++i)
        {
            for(int j = 0;j < mHeight;++j)
            {
                mCells[i][j] = src.mCells[i][j];
            }
        }
    }
    template<typename T>
    void GameBoard<T>::initialContainer()
    {
        mCells.resize(mWidth);
        for(auto &item : mCells)
        {
            item.resize(mHeight);
        }
    }

    在main函数里:

    #include <iostream>
    #include <initializer_list>
    #include "GameBoard.h"
    #include "GameBoard.cpp"
    /* run this program using the console pauser or add your own getch, system("pause") or input loop */
    
    
    int main(int argc, char** argv) 
    {    
        GameBoard<int> myIntGameBoard(10,10);
        for(size_t i = 0;i < myIntGameBoard.getWidth();++i)
        {
            for(size_t j = 0;j < myIntGameBoard.getHeight();++j)
            {
                myIntGameBoard.setElemAt(i,j,i*10+j);
            }
        }
        
        for(size_t i = 0;i < myIntGameBoard.getWidth();++i)
        {
            for(size_t j = 0;j < myIntGameBoard.getHeight();++j)
            {
                std::cout << myIntGameBoard.getElem(i,j) << " ";
            }
            std::cout << std::endl;
        }
        return 0;
    }

    其意思就是在mCells里插入数据0~99;并且打印出来;

    1>不仅仅可以实例化int型的,还可以实例化double,char,int*,char*等等;

    如果想将GameBoard对象作为参数,则这样声明:

    void myTemplateFirstFun(GameBoard<int>& inGameBoard)

    {

      //omitted for brevity

    }

    2>为了书写不那么难看和艰难,可以指定一个更加简单的名字:

    typedef GameBoard<int> IntGameBoard

    void myTemplateFirstFun(IntGameBoard& inGameBoard)

    {

      //omitted for brevity

    }

    3>还可以实例化一个类:

      假设Sheepcell是一个类:

      GameBoard<Sheepcell> mySheepCellBoard;

      Sheepcell myCell("Text");

      mySheepCellBoard.setElemt(0,0,myCell);

    4>还可以保存指针

      GameBoard<const char *> charGameBoard;

      charGameBoard.setElemt(0,0,"hello");

    5>指定的类型甚至可以是一个类模板类型:
      GameBoard<std::vector<int>> gridGameBoard;

      std::vector<int> myIntVector{1,2,3,4};

      gridGameBoard.setElemt(1,2,myIntVector);

    6>还可以在堆上动态分配GameBoard模板:

      auto myGameBoard = std::make_unique<int>(2,2);

      myGameBoard ->setElemt(1,2,10);

      int x = myGameBoard ->getElemt(1,2);

    7>讲解一下编译器处理模板的原理:

    •  选择性实例化

        比如:

      GameBoard<const char *> charGameBoard;

      charGameBoard.setElemt(0,0,"hello");

      编译器只会为const char *生成无参数的构造函数,析构函数和setElemt()的代码,不会为其他方法生成代码,例如复制构造函数,运算符等等

    8>限制模板的实例化

      希望类模板采用已知的类型比如:int,double,std::vector;就需要在源文件里显示的实例化模板(在.cpp文件最后写上)

      template class GameBoard<int>;

      template class GameBoard<double>;

      template class GameBoard<std::vector<int>>;

      这样就不允许客户用其他类型的实例化了;

      

  • 相关阅读:
    linux常用命令(18)find exec
    linux常用命令(17)find命令概览
    linux常用命令(16)locate命令
    linux常用命令(15)whereis命令
    linux常用命令(14)which命令
    linux常用命令(13)tail命令
    linux常用命令(12)head命令
    linux常用命令(11)less命令
    linux常用命令(10)more命令
    linux常用命令(9)nl命令
  • 原文地址:https://www.cnblogs.com/boost/p/10354949.html
Copyright © 2020-2023  润新知