網(wǎng)站首頁 編程語言 正文
一、提要
資源有很多種,每種都封裝一套,還是挺繁瑣的!對(duì)于比較少使用或者一個(gè)程序很可能只會(huì)用一次的資源,我們不想封裝,在這種情況下用Boost.ScopeExit。
二、退出作用域(Boost.ScopeExit)
庫(kù) Boost.ScopeExit 使得在沒有資源特定類的情況下使用 RAII 成為可能。
2.1 范例1.UsingBOOST_SCOPE_EXIT
#include <boost/scope_exit.hpp> #include <iostream> int *foo() { int *i = new int{10}; BOOST_SCOPE_EXIT(&i) { delete i; i = 0; } BOOST_SCOPE_EXIT_END std::cout << *i << '\n'; return i; } int main() { int *j = foo(); std::cout << j << '\n'; }
計(jì)算結(jié)果:
Boost.ScopeExit 提供了宏 BOOST_SCOPE_EXIT,它可以用來定義一些看起來像本地函數(shù)但沒有名字的東西。但是,它確實(shí)有一個(gè)括號(hào)中的參數(shù)列表和大括號(hào)中的塊。 必須包含頭文件 boost/scoped_exit.hpp 才能使用 BOOST_SCOPE_EXIT。
宏的參數(shù)列表包含來自外部范圍的變量,這些變量應(yīng)該可以在塊中訪問。變量通過副本傳遞。要通過引用傳遞變量,它必須以 & 符號(hào)作為前綴,如示例2.1 范例1. 中所示。
如果變量在參數(shù)列表中,則塊中的代碼只能從外部范圍訪問變量。
BOOST_SCOPE_EXIT 用于定義一個(gè)塊,該塊將在定義塊的范圍結(jié)束時(shí)執(zhí)行。在示例 3.1 中,使用 BOOST_SCOPE_EXIT 定義的塊在 foo() 返回之前執(zhí)行。
BOOST_SCOPE_EXIT 可用于從 RAII 中受益,而無需使用特定于資源的類。 foo() 使用 new 創(chuàng)建一個(gè) int 變量。為了釋放變量,使用 BOOST_SCOPE_EXIT 定義了一個(gè)調(diào)用 delete 的塊。即使函數(shù)由于異常而提前返回,也保證執(zhí)行此塊。在示例 1 中,BOOST_SCOPE_EXIT 與智能指針一樣好。
請(qǐng)注意,變量 i 在 BOOST_SCOPE_EXIT 定義的塊末尾設(shè)置為 0。然后 i 由 foo() 返回并寫入 main() 中的標(biāo)準(zhǔn)輸出流。但是,該示例不顯示 0。j 設(shè)置為隨機(jī)值 - 即 int 變量在內(nèi)存被釋放之前所在的地址。 BOOST_SCOPE_EXIT 后面的塊獲得了對(duì) i 的引用并釋放了內(nèi)存。但由于該塊是在 foo() 的末尾執(zhí)行的,因此將 0 分配給 i 為時(shí)已晚。 foo() 的返回值是在 i 設(shè)置為 0 之前創(chuàng)建的 i 的副本。
如果您使用 C++11 開發(fā)環(huán)境,則可以忽略 Boost.ScopeExit。在這種情況下,您可以在 lambda 函數(shù)的幫助下使用沒有資源特定類的 RAII。
2.2 示例2.Boost.ScopeExit和C++11的lambda函數(shù)
#include <iostream> #include <utility> template <typename T> struct scope_exit { scope_exit(T &&t) : t_{std::move(t)} {} ~scope_exit() { t_(); } T t_; }; template <typename T> scope_exit<T> make_scope_exit(T &&t) { return scope_exit<T>{ std::move(t)}; } int *foo() { int *i = new int{10}; auto cleanup = make_scope_exit([&i]() mutable { delete i; i = 0; }); std::cout << *i << '\n'; return i; } int main() { int *j = foo(); std::cout << j << '\n'; }
運(yùn)算結(jié)果:
示例2 定義了類 scope_exit,其構(gòu)造函數(shù)接受一個(gè)函數(shù)。該函數(shù)由析構(gòu)函數(shù)調(diào)用。此外,還定義了一個(gè)輔助函數(shù) make_scope_exit(),它可以在無需指定模板參數(shù)的情況下實(shí)例化 scope_exit。
在 foo() 中,一個(gè) lambda 函數(shù)被傳遞給 make_scope_exit()。 lambda 函數(shù)看起來像示例 3.1 中 BOOST_SCOPE_EXIT 之后的塊:地址存儲(chǔ)在 i 中的動(dòng)態(tài)分配的 int 變量通過刪除被釋放。然后將 0 分配給 i。
該示例與前一個(gè)示例執(zhí)行相同的操作。不僅 int 變量被刪除,而且 j 在寫入標(biāo)準(zhǔn)輸出流時(shí)也沒有設(shè)置為 0。
2.3 示例3.特點(diǎn)BOOST_SCOPE_EXIT
#include <boost/scope_exit.hpp> #include <iostream> struct x { int i; void foo() { i = 10; BOOST_SCOPE_EXIT(void) { std::cout << "last\n"; } BOOST_SCOPE_EXIT_END BOOST_SCOPE_EXIT(this_) { this_->i = 20; std::cout << "first\n"; } BOOST_SCOPE_EXIT_END } }; int main() { x obj; obj.foo(); std::cout << obj.i << '\n'; }
示例介紹了 BOOST_SCOPE_EXIT 的一些特性:
- 當(dāng) BOOST_SCOPE_EXIT 用于在一個(gè)范圍內(nèi)定義多個(gè)塊時(shí),這些塊以相反的順序執(zhí)行。示例 3 先顯示后顯示。
- 如果沒有變量將傳遞給 BOOST_SCOPE_EXIT,則需要指定 void。括號(hào)不能為空。
- 如果您在成員函數(shù)中使用 BOOST_SCOPE_EXIT 并且需要傳遞指向當(dāng)前對(duì)象的指針,則必須使用 this_ 而不是 this。
示例3:顯示first,last
, 和20
in that order.
三、練習(xí)
BOOST_SCOPE_EXIT(&flag) { } BOOST_SCOPE_EXIT_END
BOOST_SCOPE_EXIT和 BOOST_SCOPE_EXIT_END都是配合著使用的, BOOST_SCOPE_EXIT()里面可以傳入多個(gè)參數(shù)。其作用相當(dāng)于回調(diào)函數(shù),
在作用域結(jié)束之后程序會(huì)自動(dòng)調(diào)用 BOOST_SCOPE_EXIT到 BOOST_SCOPE_EXIT_END之間的代碼。
包含的頭文件是 #include <boost/scope_exit.hpp>
下面是一個(gè)簡(jiǎn)單的例子:
#include <boost/scope_exit.hpp> void PrintCout(const std::string& str) { bool submitted = false; BOOST_SCOPE_EXIT(&submitted ) { if (!submitted) std::cout<<"false"<<std::endl; else std::cout<<"true"<<std::endl; } BOOST_SCOPE_EXIT_END submitted = ((str == "Y")? true:false); } int main(int argc, char* argv[]) { std::string str; std::cin>>str; while(str != "q"){ PrintCout(str); std::cin>>str; } }
這里的 BOOST_SCOPE_EXIT()可以傳入多個(gè)參數(shù),格式:
BOOST_SCOPE_EXIT(¶meter1,¶meter2,...)
原文鏈接:https://yamagota.blog.csdn.net/article/details/127045982
相關(guān)推薦
- 2022-10-20 Python中使用Frozenset對(duì)象的案例詳解_python
- 2022-04-09 SpringBoot設(shè)置CorsFilter過濾器解決跨域問題
- 2023-11-14 python matlibplot將不同數(shù)據(jù)的柱狀圖和折線圖畫在同一張圖中
- 2022-08-21 golang協(xié)程與線程區(qū)別簡(jiǎn)要介紹_Golang
- 2022-05-05 C++繼承中的對(duì)象構(gòu)造與析構(gòu)和賦值重載詳解_C 語言
- 2022-12-02 深入理解Golang?make和new的區(qū)別及實(shí)現(xiàn)原理_Golang
- 2022-12-15 python將二維數(shù)組升為一維數(shù)組或二維降為一維方法實(shí)例_python
- 2022-12-23 利用Python實(shí)現(xiàn)簡(jiǎn)易計(jì)算器的示例代碼_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支