91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++中如何實現Go的defer功能

發布時間:2022-10-14 16:29:45 來源:億速云 閱讀:129 作者:iii 欄目:編程語言

本篇內容介紹了“C++中如何實現Go的defer功能”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

在Go語言中有一個關鍵字:defer,它的作用就是延遲執行后面的函數,在資源釋放方面特別有用,比如下面一段C/C++的示例代碼:

void test()
{
	FILE* fp = fopen("test.txt", "r");
	if (nullptr == fp)
		return;

	if (...)
	{
		fclose(fp);
		return;
	}
	if (...)
	{
		fclose(fp);
		return;
	}
	if (...)
	{
		fclose(fp);
		return;
	}
	fclose(fp);
}

在每一處返回之前都需要調用fclose來關閉文件句柄,中間的流程中斷越多,越是容易遺漏調用fclose導致未正常關閉文件。

C++可以使用shared_ptr,auto_ptr之類的智能指針來管理分配的內存,但是像上面這種情況C++并沒有現成的可使用的代碼來處理。而Go語言提供了defer關鍵字來解決此類問題,Go可以按如下方式來寫:

func test() {
	file, err := os.Open("test.txt")
	if err != nil {
		return
	}
	defer file.Close()
	if ... {
		return
	}
	if ... {
		return
	}
	if ... {
		return
	}
}

只需要使用一句:

defer file.Close()

即可,Go會自動在return之后調用defer后面的函數。我們再看看下面的示例:

package main

import (
	"fmt"
)

func test() (n int, err error) {
	defer fmt.Println("測試1")
	defer fmt.Println("測試2")
	defer fmt.Println("測試3")
	return fmt.Println("test")
}

func main() {
	test()
}

它的輸出為:

test
測試3
測試2
測試1

C++中如何實現Go的defer功能

可以看出有多個defer時,按照先進后出的方式執行的。

C++中我們可以利用析構函數來實現,而且C++的局部變量析構規則也是按照先進后出的方式執行的。為此,我們需要定義一個Defer類:

#include <functional>
typedef std::function<void()> fnDefer;
class Defer
{
public:
	Defer(fnDefer fn) : m_fn(fn)
	{
	}
	~Defer()
	{
		if(m_fn)
			m_fn();
	}
private:
	fnDefer m_fn;
};

這樣,前面的C++示例代碼可以寫成:

void test()
{
	FILE* fp = fopen("test.txt", "r");
	if (nullptr == fp)
		return;

	Defer d([&]()
	{
		fclose(fp);
	});
	if (...)
	{
		return;
	}
	if (...)
	{
		return;
	}
	if (...)
	{
		return;
	}
}

不用再在每一處返回前手動寫代碼關閉文件了。

但是這里還有一點不便之處就是需要手寫一個lambda表達式和手動定義一個變量,這個很好解決,使用宏來處理。

#define defer1(a,b) a##b
#define defer2(a, b) defer1(a, b)
#define defer(expr) Defer defer2(__Defer__,__COUNTER__) ([&](){expr;})

為了方便在同一函數多處使用,定義了defer宏來給變量命不同的名,前面的代碼可以改為:

void test()
{
	FILE* fp = fopen("test.txt", "r");
	if (nullptr == fp)
		return;

	defer(fclose(fp));
	if (...)
	{
		return;
	}
	if (...)
	{
		return;
	}
	if (...)
	{
		return;
	}
}

這樣就實用且方便得多了。下面給出完整代碼以及測試用例:

#include <functional>

using namespace std;

typedef std::function<void()> fnDefer;
class Defer
{
public:
	Defer(fnDefer fn) : m_fn(fn)
	{
	}
	~Defer()
	{
		if(m_fn)
			m_fn();
	}
private:
	fnDefer m_fn;
};

#define defer1(a,b) a##b
#define defer2(a, b) defer1(a, b)
#define defer(expr) Defer defer2(__Defer__,__COUNTER__) ([&](){expr;})

class Test
{
public:
	void f(int i)
	{
		printf("f:%d %p
", i, this);
	}
};

int main(int argc, char *argv[])
{
	Test t;
	printf("test:%p
", &t);
	defer(t.f(1));
	defer(t.f(2));
	defer(t.f(3));

	return 0;
}

結果如下:

C++中如何實現Go的defer功能

以上在VC 2015以及GCC、Clang下測試通過。

“C++中如何實現Go的defer功能”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

许昌县| 周口市| 威信县| 花莲市| 定日县| 庐江县| 平凉市| 乾安县| 九龙坡区| 托克托县| 凤山县| 米泉市| 阜新| 土默特左旗| 嘉善县| 咸阳市| 温泉县| 都安| 砚山县| 改则县| 江川县| 家居| 阿鲁科尔沁旗| 西乡县| 桂阳县| 咸丰县| 北宁市| 连山| 方城县| 阿拉善右旗| 汽车| 九寨沟县| 兴化市| 札达县| 中阳县| 什邡市| 通州市| 桂阳县| 泾源县| 顺平县| 东乌珠穆沁旗|