zoukankan      html  css  js  c++  java
  • 【面试攻略】模板和动态参数

    #pragma once
    #include "BaseGameType.h"
    #include <vector>
    #include "Log/Log.h"
    #include "Serialize/Stream.h"
    #include "GameDefine.h"
    
    #pragma pack(push,1)
    
    template <typename T, TUint32 N>
    struct StaticVector
    {
    public:
    	StaticVector()
    	{
    		m_vecLen = 0;
    	}
    	~StaticVector(){}
    
    	Tint32 GetSize() const //获取容器的总容量
    	{
    		return N;
    	}
    
    	Tint32 GetLen() const //获取数据的长度
    	{
    		return m_vecLen;
    	}
    
    	void Add(T &Data)
    	{
    		
     		if(m_vecLen >= N)
     		{
     			Log::Instance()->WriteLog(enLogType_Error,"StaticVector::Add错误");
     			return ;
     		}
    		m_vecData[m_vecLen++] = Data;
    	}
    
    	T* GetDataHead() //获取首地址
    	{
    		return m_vecData;
    	}
    
    	T& GetData(TUint32 nIndex) //获取指定位置数据
    	{
     		if(nIndex < 0 || nIndex >= m_vecLen)
     		{
     			Log::Instance()->WriteLog(enLogType_Error,"StaticVector::GetData错误");
     			return (T&)m_vecData[0];
     		}
    		return (T&)m_vecData[nIndex];
    	}
    
    	void SetData(TUint32 nIndex, T& Data)
    	{
     		if(nIndex < 0 || nIndex >= m_vecLen)
     		{
     			Log::Instance()->WriteLog(enLogType_Error,"StaticVector::SetData错误");
     			return ;
     		}
    		m_vecData[nIndex] = Data;
    	}
    
    	T& operator [] (TUint32 nIndex) const
    	{
     		if(nIndex < 0 || nIndex >= m_vecLen)
     		{
     			Log::Instance()->WriteLog(enLogType_Error,"StaticVector::[]错误");
     			return (T&)m_vecData[0];
     		}
    		return (T&)m_vecData[nIndex];
    	}
    
    	void clear()
    	{
    		m_vecLen = 0;
    	}
    
    	void Serialize( Stream& stream )
    	{
    
    		TUint16 nLen = GetLen();
    
    		stream.Write(nLen);
    
    		for (int i=0; i < nLen; i++)
    		{
    			stream.Write(GetData(i));
    		}
    	}
    
    	bool DeSerialize( Stream& stream )
    	{
    
    		TUint16 nLen = 0;
    		if (!stream.Read(nLen))
    			return false;
    
    		for (TUint16 i=0; i < nLen; i++)
    		{
    			if(GetSize() - GetLen() <=0 )
    				return false;
    
    			T data;
    			if (!stream.Read(data))
    				return false;
    			
    			Add(data);
    		}
    
    		return true;
    	}
    
    protected:
    	T m_vecData[N];
    	TUint32 m_vecLen;
    };
    
    
    #pragma pack(pop)

    至于为什么要用静态容器,是因为游戏开发玩家数据需要用到很多容器,而如果要用内存池,就必须提前知道玩家的最大内存消耗申请内存。

    void Log::WriteCriticalError(const char *pszParam, ...)
    {
    	if(pszParam == NULL)
    		return;
    
    	AutoLock locker(logLocker);
    
    	va_list va;
    	va_start(va, pszParam);
    
    	int nLen = 0;
    	char szResult[LOG_BUFFER_SIZE];
    
    	time_t t = time(0);
    	tm* Tm = localtime(&t);
    
    	nLen = strftime(szResult, LOG_BUFFER_SIZE, "%Y-%m-%d %H:%M:%S ", Tm);
    
    #ifdef WIN32
    	nLen += vsnprintf_s(szResult + nLen, LOG_BUFFER_SIZE - nLen, _TRUNCATE, pszParam, va);
    #else
    	nLen += vsprintf(szResult + nLen, pszParam, va );
    #endif
    
    	nLen += sprintf(szResult + nLen, "
    ");
        printf(szResult);
    
    #ifdef WIN32
    	MessageBoxA(NULL,szResult,"严重错误!",MB_OK);
    #else
    	WriteLog(enLogType_Error,szResult);
    #endif
    }
    void Log::PrintConsole(const char *pszParam, ...)
    {
    	int length = strlen(pszParam);
    	if(pszParam == NULL || LOG_BUFFER_SIZE <= length)
    		return;
    	AutoLock locker(logLocker);
    	char szResult[LOG_BUFFER_SIZE];
    	int resultLen = 0;
    	va_list va;
    	va_start(va, pszParam);
    	resultLen = FormatWrite(enLogType_Msg,szResult,sizeof(szResult),pszParam, va);
    	va_end(va);
    	printf(szResult);
    }
    
    void Log::WriteLog(enLogType LogType, const char *pszParam, ...)
    {
    	int length = strlen(pszParam);
    	if(pszParam == NULL || enLogType_Max <= LogType || LOG_BUFFER_SIZE <= length)
    		return;
    	if(CanWrite[LogType] == false)
    		return;
    	char szResult[LOG_BUFFER_SIZE];
    	int resultLen = 0;
    	va_list va;
    	va_start(va, pszParam);
    	resultLen = FormatWrite(LogType,szResult,sizeof(szResult),pszParam, va);
    	va_end(va);
    	LogSaveData data;
    	data.m_type = LogType;
    	data.bIsUTF8 = false;
    	data.m_count = resultLen;
    	data.m_data = szResult;
    	{
    		AutoLock locker(logLocker);
    		m_lstLogData.push_back(data);
    	}
    	m_WaitEvent.SetEvent();
    }

    比如,我们要封装一个自己的写log函数,就需要动态参数。

    参考资料

    C++ 模板 https://www.runoob.com/cplusplus/cpp-templates.html

    C++学习之可变参数的函数与模板 https://songlee24.github.io/2014/07/22/cpp-changeable-parameter/

  • 相关阅读:
    Hdu 4221 Greedy?
    Hdu 2955 Robberies
    Hdu 3309 Roll The Cube
    Hdu 2602 Bone Collector
    Hdu 2844 Coins
    Hdu 2255奔小康赚大钱
    Hdu 2120 Ice_cream's world I
    Hdu 2159 FATE
    Hdu 2102 A计划
    Hdu 2098分拆素数和
  • 原文地址:https://www.cnblogs.com/byfei/p/14104087.html
Copyright © 2011-2022 走看看