亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++實(shí)現(xiàn)Go的defer功能(示例代碼)

 更新時(shí)間:2021年07月11日 09:39:47   作者:witton  
defer和go一樣都是Go語(yǔ)言提供的關(guān)鍵字。defer用于資源的釋放,會(huì)在函數(shù)返回之前進(jìn)行調(diào)用。接下來(lái)通過(guò)本文給大家介紹C++實(shí)現(xiàn)Go的defer功能,感興趣的朋友跟隨小編一起看看吧

在Go語(yǔ)言中有一個(gè)關(guān)鍵字:defer,它的作用就是延遲執(zhí)行后面的函數(shù),在資源釋放方面特別有用,比如下面一段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);
}

在每一處返回之前都需要調(diào)用fclose來(lái)關(guān)閉文件句柄,中間的流程中斷越多,越是容易遺漏調(diào)用fclose導(dǎo)致未正常關(guān)閉文件。

C++可以使用shared_ptr,auto_ptr之類的智能指針來(lái)管理分配的內(nèi)存,但是像上面這種情況C++并沒(méi)有現(xiàn)成的可使用的代碼來(lái)處理。而Go語(yǔ)言提供了defer關(guān)鍵字來(lái)解決此類問(wèn)題,Go可以按如下方式來(lái)寫(xiě):

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會(huì)自動(dòng)在return之后調(diào)用defer后面的函數(shù)。我們?cè)倏纯聪旅娴氖纠?/p>

package main

import (
	"fmt"
)

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

func main() {
	test()
}

它的輸出為:

test
測(cè)試3
測(cè)試2
測(cè)試1

在這里插入圖片描述

可以看出有多個(gè)defer時(shí),按照先進(jìn)后出的方式執(zhí)行的。

C++中我們可以利用析構(gòu)函數(shù)來(lái)實(shí)現(xiàn),而且C++的局部變量析構(gòu)規(guī)則也是按照先進(jìn)后出的方式執(zhí)行的。為此,我們需要定義一個(gè)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++示例代碼可以寫(xiě)成:

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

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

不用再在每一處返回前手動(dòng)寫(xiě)代碼關(guān)閉文件了。

但是這里還有一點(diǎn)不便之處就是需要手寫(xiě)一個(gè)lambda表達(dá)式和手動(dòng)定義一個(gè)變量,這個(gè)很好解決,使用宏來(lái)處理。

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

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

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

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

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

#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\n", i, this);
	}
};

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

	return 0;
}

結(jié)果如下:

在這里插入圖片描述

以上在VC 2015以及GCC、Clang下測(cè)試通過(guò)。

到此這篇關(guān)于C++實(shí)現(xiàn)Go的defer功能(示例代碼)的文章就介紹到這了,更多相關(guān)Go關(guān)鍵字defer內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • C/C++利用原生套接字抓取FTP數(shù)據(jù)包

    C/C++利用原生套接字抓取FTP數(shù)據(jù)包

    這篇文章主要為大家詳細(xì)介紹了如何基于原始套接字的網(wǎng)絡(luò)數(shù)據(jù)包捕獲與分析工具,通過(guò)實(shí)時(shí)監(jiān)控網(wǎng)絡(luò)流量,實(shí)現(xiàn)抓取流量包內(nèi)的FTP通信數(shù)據(jù),需要的小伙伴可以參考下
    2023-12-12
  • C++下標(biāo)運(yùn)算符詳解

    C++下標(biāo)運(yùn)算符詳解

    C語(yǔ)言中的下標(biāo)運(yùn)算符用于訪問(wèn)數(shù)組或指針變量中的元素,它使用方括號(hào) [] 來(lái)表示,并在方括號(hào)內(nèi)指定元素的索引位置,本文給大家詳細(xì)的講解一下C++的下標(biāo)運(yùn)算符,需要的朋友可以參考下
    2023-09-09
  • C++類模板實(shí)戰(zhàn)之vector容器的實(shí)現(xiàn)

    C++類模板實(shí)戰(zhàn)之vector容器的實(shí)現(xiàn)

    本文我們將做一個(gè)類模板實(shí)戰(zhàn)-手寫(xiě)精簡(jiǎn)版vector容器。讓我們自己封裝一個(gè)數(shù)組類,可以適應(yīng)基本數(shù)據(jù)類型和自定義數(shù)據(jù)類型,感興趣的可以了解一下
    2022-07-07
  • C++中與輸入相關(guān)的istream類成員函數(shù)簡(jiǎn)介

    C++中與輸入相關(guān)的istream類成員函數(shù)簡(jiǎn)介

    這篇文章主要介紹了C++中與輸入相關(guān)的istream類成員函數(shù)簡(jiǎn)介,包括eof函數(shù)和peek函數(shù)以及putback函數(shù)還有ignore函數(shù),需要的朋友可以參考下
    2015-09-09
  • c語(yǔ)言中的二級(jí)指針做函數(shù)參數(shù)說(shuō)明

    c語(yǔ)言中的二級(jí)指針做函數(shù)參數(shù)說(shuō)明

    這篇文章主要介紹了c語(yǔ)言中的二級(jí)指針做函數(shù)參數(shù)說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • C++淺析虛函數(shù)使用方法

    C++淺析虛函數(shù)使用方法

    對(duì)C++了解的人都應(yīng)該知道虛函數(shù)(Virtual Function)是通過(guò)一張?zhí)摵瘮?shù)表(Virtual Table)來(lái)實(shí)現(xiàn)的。簡(jiǎn)稱為V-Table。本文就將詳細(xì)講講虛函數(shù)表的原理與使用,需要的可以參考一下
    2022-08-08
  • Recommended C Style and Coding Standards中文翻譯版

    Recommended C Style and Coding Standards中文翻譯版

    本文翻譯自Recommended C Style and Coding Standards(C語(yǔ)言編碼風(fēng)格和標(biāo)準(zhǔn)),需要的朋友可以參考下
    2014-04-04
  • C++ Qt開(kāi)發(fā)之PushButton按鈕組件的使用詳解

    C++ Qt開(kāi)發(fā)之PushButton按鈕組件的使用詳解

    Qt 是一個(gè)跨平臺(tái)C++圖形界面開(kāi)發(fā)庫(kù),利用Qt可以快速開(kāi)發(fā)跨平臺(tái)窗體應(yīng)用程序,本文將重點(diǎn)介紹QPushButton按鈕組件的常用方法及靈活運(yùn)用,感興趣的小伙伴可以學(xué)習(xí)一下
    2023-12-12
  • C++中的vector使用詳解及重要部分底層實(shí)現(xiàn)

    C++中的vector使用詳解及重要部分底層實(shí)現(xiàn)

    本篇文章會(huì)對(duì)vector的語(yǔ)法使用進(jìn)行詳解,同時(shí),還會(huì)對(duì)重要難點(diǎn)部分的底層實(shí)現(xiàn)進(jìn)行講解,其中有vector的迭代器失效和深拷貝問(wèn)題,希望本篇文章的內(nèi)容會(huì)對(duì)你有所幫助
    2023-07-07
  • C語(yǔ)言中數(shù)組常用的一些排序算法小結(jié)

    C語(yǔ)言中數(shù)組常用的一些排序算法小結(jié)

    數(shù)組的排序方法有很多,效率也各不相同,下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言中數(shù)組常用的一些排序算法的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01

最新評(píng)論