目前共有5篇帖子。 內容轉換:不轉換▼
 
點擊 回復
268 4
我终于完成了一个我写过的最复杂的一个C++类。。。
一派護法 十九級
1樓 發表于:2016-6-7 14:50

#pragma once

#define PL_FREENAME 2
#define PL_FREEVALUE 1

typedef struct _tagParam
{
    LPWSTR lpszName;
    LPWSTR lpszValue;
    UINT uFree;
    struct _tagParam *pNext;
} PARAMW, *LPPARAMW;

#ifdef _PARAMLIST_EXPORT
class _declspec(dllexport) ParamListW
#else
class ParamListW
#endif
{
public:
    ParamListW(void);
    ParamListW(LPCWSTR lpSource);
    ParamListW(const ParamListW &pl);
    ~ParamListW(void);

    ParamListW &operator = (const ParamListW &pl);
    friend ParamListW operator + (const LPWSTR &a, const ParamListW &pl);
    ParamListW operator + (const ParamListW &pl);
    ParamListW &operator += (const ParamListW &pl);

    static void CopyParam(LPPARAMW lpDest, LPPARAMW lpSource);
    static void CopyParam(LPPARAMW lpSource, LPWSTR *ppName, LPWSTR *ppValue);
    static void FreeParam(LPPARAMW lpParam);

    UINT Combine(const ParamListW &pl, bool bMerge = true);
    void CopyParam(LPPARAMW lpSource);
    UINT Count(void) const;
    LPWSTR GetResult(void) const;
    bool HasParam(LPCWSTR szName, LPPARAMW *ppParam = NULL) const;
    bool IsEmpty(void) const;
    void RemoveAll(void);
    bool RemoveParam(LPCWSTR szName);
    void SetParam(LPWSTR szName, int nValue);
    void SetParam(LPWSTR szName, LPWSTR szValue, UINT uFree = NULL);
    void SetParam(LPWSTR szName, WCHAR ch);
    void SetResult(LPCWSTR lpSource);

protected:
    LPPARAMW pParams;
    LPPARAMW pRear;
};

//#ifdef _UNICODE
typedef ParamListW ParamList;
/*#else
typedef ParamListA ParamList;
#endif*/

一派護法 十九級
2樓 發表于:2016-6-7 14:52

ParamListW operator + (const LPWSTR &a, const ParamListW &pl)
{
    ParamListW obj(a);
    obj.Combine(pl);
    return obj;
}
在头文件外实现函数时,不能加上类名“ParamListW::”
这是个友元普通函数,而非成员函数
一派護法 十九級
3樓 發表于:2016-6-7 14:55

当重载“基本类型 + 类对象”时,需要定义一个名为operator+的普通函数,并在类中声明为友元,参数个数为两个。
只有重载”类对象 + 基本类型”时,才在类中定义“operator+”成员函数,参数个数为一个。
函数的返回值为加法运算的结果。
参数必须是const修饰。
而且此时const LPWSTR不能写成LPCWSTR
一派護法 十九級
4樓 發表于:2016-6-7 14:57

#include "stdafx.h"
#include "Unicode.h"
#define _PARAMLIST_EXPORT
#include "ParamList.h"

#define INVALID_NAME(name) ((name) == NULL || *(name) == '\0')

ParamListW::ParamListW(void)
{
    pParams = pRear = NULL;
}

ParamListW::ParamListW(LPCWSTR lpSource)
{
    pParams = pRear = NULL;
    SetResult(lpSource);
}

ParamListW::ParamListW(const ParamListW &pl)
{
    pParams = pRear = NULL;
    operator = (pl);
}


ParamListW::~ParamListW(void)
{
    RemoveAll();
}

ParamListW &ParamListW::operator = (const ParamListW &pl)
{
    LPPARAMW p = pl.pParams;
    LPPARAMW p2 = NULL;
    RemoveAll();
    while (p != NULL)
    {
        if (p2 == NULL)
            pParams = p2 = (LPPARAMW)malloc(sizeof(PARAMW));
        else
        {
            p2->pNext = (LPPARAMW)malloc(sizeof(PARAMW));
            p2 = p2->pNext;
        }
        CopyParam(p2, p);
        p = p->pNext;
    }
    if (p2 != NULL)
    {
        p2->pNext = NULL;
        pRear = p2;
    }
    return *this;
}

// Warning: A + B != B + A
ParamListW operator + (const LPWSTR &a, const ParamListW &pl)
{
    ParamListW obj(a);
    obj.Combine(pl);
    return obj;
}

ParamListW ParamListW::operator + (const ParamListW &pl)
{
    ParamListW obj(*this);
    obj.Combine(pl);
    return obj;
}

ParamListW &ParamListW::operator += (const ParamListW &pl)
{
    Combine(pl);
    return *this;
}

UINT ParamListW::Combine(const ParamListW &pl, bool bMerge)
{
    UINT uCount = 0;
    LPPARAMW p;
    for (p = pl.pParams; p != NULL; p = p->pNext)
    {
        if (!bMerge && HasParam(p->lpszName))
            continue;

        CopyParam(p);
        uCount++;
    }
    return uCount;
}

void ParamListW::CopyParam(LPPARAMW lpDest, LPPARAMW lpSource)
{
    CopyParam(lpSource, &lpDest->lpszName, &lpDest->lpszValue);
    lpDest->uFree = lpSource->uFree;
}

void ParamListW::CopyParam(LPPARAMW lpSource)
{
    LPWSTR pName, pValue;
    CopyParam(lpSource, &pName, &pValue);
    SetParam(pName, pValue, lpSource->uFree);
}

void ParamListW::CopyParam(LPPARAMW lpSource, LPWSTR *ppName, LPWSTR *ppValue)
{
    if (lpSource->uFree & PL_FREENAME)
        *ppName = DuplicateStringW(lpSource->lpszName);
    else
        *ppName = lpSource->lpszName;
    if (lpSource->uFree & PL_FREEVALUE)
        *ppValue = DuplicateStringW(lpSource->lpszValue);
    else
        *ppValue = lpSource->lpszValue;
}

UINT ParamListW::Count(void) const
{
    UINT n = 0;
    LPPARAMW p = pParams;
    while (p != NULL)
    {
        n++;
        p = p->pNext;
    }
    return n;
}

void ParamListW::FreeParam(LPPARAMW lpParam)
{
    if (lpParam->uFree & PL_FREENAME)
    {
        free(lpParam->lpszName);
        lpParam->lpszName = NULL;
    }
    if (lpParam->uFree & PL_FREEVALUE)
    {
        free(lpParam->lpszValue);
        lpParam->lpszValue = NULL;
    }
}

LPWSTR ParamListW::GetResult(void) const
{
    LPPARAMW p = pParams;
    LPWSTR lpResult = NULL;
    size_t cchTotal = 0;
    bool bFirst = true;
    while (p != NULL)
    {
        LPWSTR p1 = URLEncodeW(p->lpszName);
        LPWSTR p2 = URLEncodeW(p->lpszValue);
        size_t cch1 = wcslen(p1);
        size_t cch2 = (p->lpszValue == NULL) ? 0 : wcslen(p2);
        size_t cchExtend = cch1 + cch2 + 3; // 3 more bytes for '&', '=' and '\0'
        lpResult = (LPWSTR)realloc(lpResult, (cchTotal + cchExtend) * sizeof(WCHAR));

        LPWCH pStr = lpResult + cchTotal;
        if (!bFirst)
            *pStr++ = L'&';
        memcpy(pStr, p1, cch1 * sizeof(WCHAR));
        pStr += cch1;
        if (p2 != NULL)
        {
            *pStr++ = L'=';
            memcpy(pStr, p2, cch2 * sizeof(WCHAR));
            pStr += cch2;
        }

        cchTotal = pStr - lpResult;
        free(p1);
        free(p2);
        p = p->pNext;
        bFirst = false;
    }
    if (lpResult != NULL)
        *(lpResult + cchTotal) = L'\0';
    return lpResult;
}

bool ParamListW::HasParam(LPCWSTR szName, LPPARAMW *ppParam) const
{
    LPPARAMW p = pParams;
    while (p != NULL)
    {
        if (wcscmp(p->lpszName, szName) == 0)
        {
            if (ppParam != NULL)
                *ppParam = p;
            return true;
        }
        p = p->pNext;
    }
    if (ppParam != NULL)
        *ppParam = NULL;
    return false;
}

bool ParamListW::IsEmpty(void) const
{
    return pParams == NULL;
}

void ParamListW::RemoveAll(void)
{
    if (pParams == NULL)
        return;

    LPPARAMW p = pParams;
    LPPARAMW temp;
    while (p != NULL)
    {
        temp = p->pNext;
        FreeParam(p);
        free(p);
        p = temp;
    }

    pParams = pRear = NULL;
}

bool ParamListW::RemoveParam(LPCWSTR szName)
{
    LPPARAMW p = pParams;
    LPPARAMW pPrev = NULL;
    while (p != NULL)
    {
        if (wcscmp(p->lpszName, szName) == 0)
        {
            if (pPrev != NULL)
                pPrev->pNext = p->pNext;
            else
                pParams = p->pNext; // change head
            if (p->pNext == NULL)
                pRear = pPrev; // change rear
            
            FreeParam(p);
            free(p);
            return true;
        }

        pPrev = p;
        p = p->pNext;
    }
    return false;
}

void ParamListW::SetParam(LPWSTR szName, int nValue)
{
    if (INVALID_NAME(szName))
        return;

    LPWSTR buf = (LPWSTR)malloc(30 * sizeof(WCHAR));
    _itow_s(nValue, buf, 30, 10);
    SetParam(szName, buf, PL_FREEVALUE);
}

void ParamListW::SetParam(LPWSTR szName, LPWSTR szValue, UINT uFree)
{
    if (INVALID_NAME(szName))
        return;

    LPPARAMW p;
    if (!HasParam(szName, &p))
    {
        /* Create a param at the end of pParams */
        p = (LPPARAMW)malloc(sizeof(PARAMW));
        p->pNext = NULL;
        if (pRear != NULL)
        {
            // Update pRear
            pRear->pNext = p;
            pRear = p;
        }
        else
            pParams = pRear = p; // first-created param
    }
    else
    {
        /* Change the param */
        FreeParam(p); // free old data
    }
    p->lpszName = szName; // force to use the new lpszName pointer
    p->lpszValue = szValue;
    p->uFree = uFree;
}

void ParamListW::SetParam(LPWSTR szName, WCHAR ch)
{
    if (INVALID_NAME(szName))
        return;

    LPWSTR buf = (LPWSTR)malloc(2 * sizeof(WCHAR));
    buf[0] = ch;
    buf[1] = L'\0';
    SetParam(szName, buf, PL_FREEVALUE);
}

void ParamListW::SetResult(LPCWSTR lpSource)
{
    LPWSTR lpszName = NULL;
    LPWSTR lpszValue = NULL;
    bool bFlag = false;
    RemoveAll();
    while (true)
    {
        if (*lpSource == L'?' || *lpSource == L'&' || *lpSource == L'\0')
        {
            if (bFlag)
                SetParam(lpszName, NULL, PL_FREENAME); // Pending ?param or &param (without value)
            if (*lpSource == L'\0')
                break;

            bFlag = false;
            lpSource++;
        }
        else if (*lpSource == L'=')
        {
            bFlag = true;
            lpSource++;
        }
    
        LPWSTR pPart, pDecodedPart;
        LPCWSTR pPartStart = lpSource;
        while (*lpSource != '\0' && *lpSource != '=' && *lpSource != '&')
            lpSource++;
        size_t cbPartSize = (lpSource - pPartStart) * sizeof(WCHAR);
        pPart = (LPWSTR)malloc(cbPartSize + sizeof(WCHAR));
        memcpy(pPart, pPartStart, cbPartSize);
        *(LPWCH)((LPBYTE)pPart + cbPartSize) = L'\0';
        pDecodedPart = URLDecodeW(pPart);
        free(pPart);

        if (!bFlag)
            lpszName = pDecodedPart;
        else
        {
            lpszValue = pDecodedPart;
            SetParam(lpszName, lpszValue, PL_FREENAME | PL_FREEVALUE);
            lpszName = lpszValue = NULL;
        }
        bFlag = !bFlag;
    }
}

一派護法 十九級
5樓 發表于:2016-6-7 15:16

ParamList类主要用到了单向链表和运算符重载(包括复制构造函数)

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
(快捷鍵:Ctrl+Enter)
 

本帖信息

點擊數:268 回複數:4
評論數: ?
作者: 巨大八爪鱼
最後回復:巨大八爪鱼
最後回復時間:2016-6-7 15:16
 
©2010-2024 Arslanbar Ver2.0
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。