網站首頁 編程語言 正文
一、說明
以下庫用于設計模式。
- Boost.Flyweight 有助于在程序中使用許多相同的對象并且需要減少內存消耗的情況。
- Boost.Signals2 使得使用觀察者設計模式變得容易。這個庫被稱為 Boost.Signals2 因為它實現了信號/槽的概念。
- Boost.MetaStateMachine 使得將狀態機從 UML 轉移到 C++ 成為可能。
本節內容
66. Boost.Flyweight
67. Boost.Signals2
68. Boost.MetaStateMachine
二、庫Boost.Flyweight
Boost.Flyweight?
Boost.Flyweight 是一個可以輕松使用同名設計模式的庫。當許多對象共享數據時,享元有助于節省內存。使用這種設計模式,不是在對象中多次存儲相同的數據,而是將共享數據保存在一個地方,所有對象都引用該數據。雖然您可以使用例如指針來實現此設計模式,但使用 Boost.Flyweight 更容易。
示例 66.1。沒有 Boost.Flyweight 的十萬個相同的字符串
#include <string>
#include <vector>
struct person
{
int id_;
std::string city_;
};
int main()
{
std::vector<person> persons;
for (int i = 0; i < 100000; ++i)
persons.push_back({i, "Berlin"});
}
Example?66.1?
示例 66.1 創建了十萬個 person 類型的對象。 person 定義了兩個成員變量:id_ 標識人,city_ 存儲人們居住的城市。在這個例子中,所有人都住在柏林。這就是為什么 city_ 在所有十萬個對象中都設置為“Berlin”。因此,該示例使用十萬個字符串,所有字符串都設置為相同的值。使用 Boost.Flyweight,可以使用一個字符串——而不是數千個——并且可以減少內存消耗。
示例 66.2。使用 Boost.Flyweight 一個字符串而不是十萬個字符串
#include <boost/flyweight.hpp>
#include <string>
#include <vector>
#include <utility>
using namespace boost::flyweights;
struct person
{
int id_;
flyweight<std::string> city_;
person(int id, std::string city) : id_{id}, city_{std::move(city)} {}
};
int main()
{
std::vector<person> persons;
for (int i = 0; i < 100000; ++i)
persons.push_back({i, "Berlin"});
}
要使用 Boost.Flyweight,請包含 boost/flyweight.hpp,如示例 66.2 所示。 Boost.Flyweight 提供了額外的頭文件,僅當您需要更改詳細的庫設置時才需要包含這些頭文件。
所有類和函數都在命名空間 boost::flyweights 中。示例 66.2 僅使用類 boost::flyweights::flyweight,這是該庫中最重要的類。成員變量 city_ 使用類型 flyweight<std::string> 而不是 std::string。這是您需要更改的所有內容,以使用此設計模式并減少程序的內存需求。
示例 66.3。多次使用 boost::flyweights::flyweight
#include <boost/flyweight.hpp>
#include <string>
#include <vector>
#include <utility>
using namespace boost::flyweights;
struct person
{
int id_;
flyweight<std::string> city_;
flyweight<std::string> country_;
person(int id, std::string city, std::string country)
: id_{id}, city_{std::move(city)}, country_{std::move(country)} {}
};
int main()
{
std::vector<person> persons;
for (int i = 0; i < 100000; ++i)
persons.push_back({i, "Berlin", "Germany"});
}
Example?66.3?
示例 66.3 向類 person 添加了第二個成員變量 country_。這個成員變量包含人們居住的國家的名字。因為在這個例子中,所有人都住在柏林,所以他們都住在同一個國家。這就是為什么在成員變量 country_ 的定義中也使用了 boost::flyweights::flyweight。
Boost.Flyweight 使用一個內部容器來存儲對象。它確保不能有多個具有相同值的對象。默認情況下,Boost.Flyweight 使用哈希容器,例如 std::unordered_set。對于不同的類型,使用不同的散列容器。與示例 66.3 一樣,成員變量 city_ 和 country_ 都是字符串;因此,只使用一個容器。在此示例中,這不是問題,因為容器僅存儲兩個字符串:“Berlin”和“Germany”。如果必須存儲許多不同的城市和國家,最好將城市存儲在一個容器中,將國家存儲在另一個容器中。
示例 66.4。多次使用 boost::flyweights::flyweight 標簽
#include <boost/flyweight.hpp>
#include <string>
#include <vector>
#include <utility>
using namespace boost::flyweights;
struct city {};
struct country {};
struct person
{
int id_;
flyweight<std::string, tag<city>> city_;
flyweight<std::string, tag<country>> country_;
person(int id, std::string city, std::string country)
: id_{id}, city_{std::move(city)}, country_{std::move(country)} {}
};
int main()
{
std::vector<person> persons;
for (int i = 0; i < 100000; ++i)
persons.push_back({i, "Berlin", "Germany"});
}
示例 66.4 將第二個模板參數傳遞給 boost::flyweights::flyweight。這是一個標簽。標簽是任意類型,僅用于區分 city_ 和 country_ 所基于的類型。示例 66.4 定義了兩個空結構城市和國家,用作標簽。但是,該示例可以改為使用 int、bool 或任何類型。
標簽使 city_ 和 country_ 使用不同的類型。現在 Boost.Flyweight 使用了兩個哈希容器——一個存儲城市,另一個存儲國家。
示例 66.5。 boost::flyweights::flyweight 的模板參數
#include <boost/flyweight.hpp>
#include <boost/flyweight/set_factory.hpp>
#include <boost/flyweight/no_locking.hpp>
#include <boost/flyweight/no_tracking.hpp>
#include <string>
#include <vector>
#include <utility>
using namespace boost::flyweights;
struct person
{
int id_;
flyweight<std::string, set_factory<>, no_locking, no_tracking> city_;
person(int id, std::string city) : id_{id}, city_{std::move(city)} {}
};
int main()
{
std::vector<person> persons;
for (int i = 0; i < 100000; ++i)
persons.push_back({i, "Berlin"});
}
標簽以外的模板參數可以傳遞給 boost::flyweights::flyweight。示例 66.5 通過 boost::flyweights::set_factory、boost::flyweights::no_locking 和 boost::flyweights::no_tracking。包含額外的頭文件以使用這些類。
boost::flyweights::set_factory 告訴 Boost.Flyweight 使用排序容器,例如 std::set,而不是散列容器。使用 boost::flyweights::no_locking,通常默認激活的對多線程的支持被停用。 boost::flyweights::no_tracking 告訴 Boost.Flyweight 不要跟蹤存儲在內部容器中的對象。默認情況下,當不再使用對象時,Boost.Flyweight 會檢測到這一點并將它們從容器中移除。當設置了 boost::flyweights::no_tracking 時,檢測機制被禁用。這提高了性能。但是,容器只能增長,永遠不會收縮。
Boost.Flyweight 支持額外的設置。如果您對調整的更多細節感興趣,請查看官方文檔。
煉習
使用 Boost.Flyweight 改進這個程序。使用禁用多線程支持的 Boost.Flyweight:
#include <string>
#include <vector>
#include <memory>
int main()
{
std::vector<std::shared_ptr<std::string>> countries;
auto germany = std::make_shared<std::string>("Germany");
for (int i = 0; i < 500; ++i)
countries.push_back(germany);
auto netherlands = std::make_shared<std::string>("Netherlands");
for (int i = 0; i < 500; ++i)
countries.push_back(netherlands);
}
原文鏈接:https://yamagota.blog.csdn.net/article/details/128164604
相關推薦
- 2023-06-21 Python生成元組和字典的方法_python
- 2022-11-16 python3?如何解壓縮.gz文件_python
- 2022-03-30 Android中圖片占用內存的深入分析_Android
- 2023-03-20 python如何在pygame中設置字體并顯示中文詳解_python
- 2023-01-05 Kotlin?協程與掛起函數及suspend關鍵字深入理解_Android
- 2023-05-21 golang代碼中調用Linux命令_Golang
- 2022-01-21 如何保證Redis緩存與數據庫的一致性?
- 2022-04-21 python的變量和運算符你都知道多少_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支