作爲C++程序員怎麼能不會這些技巧?

直入主題

作爲C++程序員你不知道這些技巧?這哪能行?趕緊來學學。 以下是我在平時項目開發中常喜歡使用的一些技巧,希望對你有所幫助。
(在恰當時候使用一些技巧能讓你的代碼變得更加美)

(一)do{}while(false)使用

在寫代碼的時候有沒這種情況,僞代碼:

void model()
{
    if (條件1)
    {
        ...;        // ...其他代碼
        if (條件2)
        {
            ...;
            if (條件3)
            {
                
            }
        }
    }
    
    other code; // 必須執行的代碼
}

有時候可能會遇到這種情況,最後面的other code是必須執行的代碼,然後上面又很多判斷條件,一直if…if…if…,看着看着就辣眼睛了。
這時候可以考慮使用下do{} while(false); 僞代碼:

void model()
{
    do
    {
        if (!條件1) break;
        ...;    // 其他代碼
        
        if (!條件2) break;
        ...;    // 其他代碼
        
        if (!條件3) break;
        ...;
        
    } while(false);
    
    other code; // 必須執行的代碼
}

while(false)讓我們的代碼只執行一次,但我們可以通過break讓代碼跳出該模塊,而消除了某些情況下多次if導致的代碼可讀性差。

(二)union

聯合體大家都有在書上看到吧?對於初學C++的小夥伴可能不瞭解爲啥要用他。雖然不是啥新鮮技巧了,但還是說說吧!
在項目開發中我時常喜歡使用聯合體來作爲索引的轉換,如你是名玩家那你所在的服務器ID,跟你的個人ID組合起來在全服中就是唯一值,那麼要怎麼拿到這個唯一值呢?

    union RoleKey
    {
        struct {
            uint32 nSerId;
            uint32 nGuid;
        }
        uint64 nValue;
    }
    
    // 那麼我們在這裏獲取64位的唯一值
    const uint64 GetRoleKey(uint32 serverId, uint32 guid)
    {
        RoleKey key;
        key.nSerId = serverId;
        key.nGuid = guid;
        
        return key.nValue;
    }

利用聯合體的機制我們很容易的將低32位設置爲了服務器ID,高32位設置爲了個人ID,最終通過聯合體機制獲得了64位唯一值。

(三)結構體初始化

正常情況下可能是這樣的?

struct Model
{
	uint32 id;
	uint32 type;
	uint32 param;

	Model()
	{
	    // 每次新增一個結構體我們都加一個構造函數來初始化
		memset(this, 0, sizeof(*this));
	}

};

那現在是怎麼樣的?不急不急,使用一些小技巧可以讓我們節省代碼的同時不容易犯錯,往下看。

// 模板類
template <typename T>
class ZeroStruct
{
public:
	ZeroStruct()
	{
		memset(this, 0, sizeof(T));
	}
};

// 沒錯現在是這樣的
struct Model : ZeroStruct<Model>
{
	uint32 id;
	uint32 type;
	uint32 param;
};

通過繼承模板類的方式來達到很方便的初始化,看個人喜好使用。

(四)tuple的使用

沒錯這是元組,學過其他語言的童鞋們應該很羨慕其他語言(如:python),他們有元組,可以支持任意類型的數據類型。 我在這裏提出只是讓不瞭解的童鞋們知道C++11後,C++也支持了元組,它就是——tuple。
爲了簡單理解啥是元組,其實我們可以拿pair來做比較,pair支持兩個參數如:std::pair<int, std::string> _pair; 而tople是可很多參數的,具體看如下代碼。


using testTuple = std::tuple<int, float, string>;

void test()
{
    static const std::vector<testTuple> testVec = {
		make_tuple(1, 1.0f,	"is -> 1"),
        make_tuple(2, 2.0f,	"is -> 2")
	};
    
    for (auto& e : test)
    {
        const testTuple _tuple = e;
        // 通過get方法即可獲取
        int nNum        = get<0>(_tuple);
        float fNum      = get<1>(_tuple);
        std::string str = get<2>(_tuple);
    }
}

通過使用tuple,很多情況下我們可以不使用結構體了。

(五)enum 中加class

如果全局中使用enum,很可能導致枚舉類型的命名衝突,這時加class能很好的防止命名衝突,非常推薦使用。

enum class ModeType
{
	Type_One	= 1,
	Type_Two	= 2,
	Type_Three	= 3,
};

先總結這幾點,後續如果有其他好用的技巧我會更新上來,也歡迎童鞋們有好的技巧能分享給我。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章