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>>;

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

  

原文地址:https://www.cnblogs.com/boost/p/10354949.html