C++與Lua閉包

起因

做遊戲開發多少會接觸lua,其中閉包也是挺常見的一種了,因爲使用lua閉包的緣故,我就嘗試着在C++使用lambda來寫個。

代碼分析

以下是lua的閉包代碼:

function fun1(param1)
	local i = param1
	return function()
		i = i + 1
		return i
	end
end

local test1 = fun1(1)
local test2 = fun1(1)	
print("test1_1...." .. test1())
print("test1_2...." .. test1())
print("test2_1...." .. test2())
print("test2_2...." .. test2())

如果對閉包不瞭解來看看輸出結果如何?
在這裏插入圖片描述

現在知道結果了,讓我們來分析分析這段代碼吧!

已經瞭解閉包的小夥伴可以跳過這段
從輸出上分析: test1與test2的值可以看出是互不影響的,並且同一個test1執行多次後值是疊加的,說明這個i並沒有像我們寫C++時候函數執行完就銷燬。爲了簡單的比喻,在看到閉包時,你可以把他想象成一個類,並結合閉包結構分析,可以想成如下:

class fun1()
{
public:
	fun1(int _i) : i(_i) {}

	int GetAddOneNum()
	{
		return ++i; 
	}

private:
	int i;
}

我們將上面lua代碼比作先創建一個 fun1 類對象 test1,而 test1() 則比作爲 test1.GetAddOneNum();,是不是就好像剛剛閉包的執行結果了?如果覺得不太形象你可以嘗試着吧GetAddOneNum改寫爲重載 () 這個運算符。

閉包則是一個函數在帶上了狀態,讓這個函數有了自己的變量如剛剛的 i 變量。

我們按照lua的模板來寫一個C++代碼。
return function() i = i + 1 return i end
返回的不就是一個函數嗎,那我們C++中使用lambda就行了,而有個問題是變量,我們在C++中並不能像lua那樣,我們執行完 fun() 函數後 i 就被銷燬了,所以改下成了如下代碼,動態的給他分配內存,防止內存管理上的問題不用猶豫用智能指針。
以下是改裝後的C++代碼:

auto fun(int _i)
{
	shared_ptr<int> i = make_shared<int>(_i);
	return [=]() -> int {
		*i += 1;
		return *i;
	};
}

int main()
{
	auto test1 = fun(1);
	auto test2 = fun(100);
	std::cout << "test1_1..." << test1() << std::endl;
	std::cout << "test1_2..." << test1() << std::endl;
	std::cout << "test2_1..." << test2() << std::endl;
	std::cout << "test2_2..." << test2() << std::endl;

    return 0;	
}

看看執行結果吧?
在這裏插入圖片描述

實驗得真知,從結果上可以看出方法是可行的,而這段C++代碼我就不解釋了,跟上面差不多的。

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