Boost程序库完全开发指南-读书笔记

2024-06-14 09:38

本文主要是介绍Boost程序库完全开发指南-读书笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Boost程序库完全开发指南——深入C++“准”标准库》读书笔记(一)

作者:gysutantoman

注:文字、程序片段大部分摘录自书中。

1.scoped_ptr1).scoped_ptr所有权严格,不能转让,一旦scoped_ptr获取了对象的管理权,你就无法再从它那里取回来。2).scoped_ptr对象生命期结束时,析构函数~scoped_ptr()会使用delete操作符回收资源。3).reset()功能重置scoped_ptr,删除原来保存的指针,在保存新指针值。这个函数不应该被调用。4).scoped_ptr不允许拷贝、赋值。下面的代码是错误的。scoped_ptr<string> sp(new string("text"));scoped_ptr<string> sp2 = sp;			//errorsp.reset(new string("another new text"));	//拥有新指针5).不能用在标准容器里。2.share_ptr1).关于构造函数(1).shared_ptr(shared_ptr const & r)从另外一个shared_ptr获得指针的管理权,同时引用计数加1,结果是两个shared_ptr共享一个指针的管理权;(2).operator=赋值操作符可以从另外一个shared_ptr或auto_ptr获得指针的管理权,其行为同构造函数;(3).shared_ptr(Y *p, D d)行为类似shared_ptr(Y *p),但使用参数d指定了析构时的定制删除器,而不是简单的delete。2).shared_ptr的reset()函数作用是将应用技术减1,停止对指针的共享。但参数的reset()则类似相同形式的构造函数,原指针应用技术减1的同事改为管理另一个指针。3).unique()在shared_ptr是指针的唯一所有者时返回true,是可靠的。4).use_count()返回当前指针的引用技术,但有的时候是不可用的。5).多态情况下:(1).把一个基类指针转型为一个子类指针或者反过来,需要使用提供的转型函数:static_pointer_cast<T>()const_pointer_cast<T>()dynamic_pointer_case<T>()返回的是转型后的shared_ptr。下面是书中的例子://class bad_exception : public exception {};shared_ptr<std::exception> sp1(new bad_exception("error"));shared_ptr<bad_exception>  sp2 = dynamic_pointer_cast<bad_exception>(sp1);shared_ptr<std::exception> sp3 = static_pointer_cast<std::exception>(sp2);6).shared_ptr支持流输出操作符operator<<,输出内部的指针值,方便调试。3.make_shared<T>()make_shared<T>()消除显式的new调用,创建一个shared_ptr<T>的对象并返回。书中的例子:shared_ptr<string> sp = make_shared<string>("make_shared");shared_ptr<vector<int> > spv = make_shared<vector<int> >(10, 2);assert(spv->size() == 10);4.weak_ptr1).为配合shared_ptr而引入的一种智能指针,它更像是shared_ptr的一个助手而不是智能指针,它最大的作用在于协助shared_ptr工作,像旁观者那样观测资源的使用情况。2).可以从一个shared_ptr或者另一个weak_ptr对象构造,获得资源的观测权。但weak_ptr没有共享资源,它的构造函数不会引起指针引用计数的增加。析构时也不会导致计数的减少。3).use_count()可以观测资源的引用计数。4).expired()功能等同于use_count==0,但更快。5).lock()从北观测的shared_ptr获得一个可用的shared_ptr对象,从而操作资源。但当expired()==true的时候,lock()函数将返回一个存储空指针的shared_ptr。下面是书中的例子:shared_ptr<int> sp(new int(10));assert(sp.use_count() == 1);weak_ptr<int> wp(sp);assert(wp.use_count() == 1);if (!wp.expired()){shared_ptr<int> sp2 = wp.lock();*sp2 = 100;assert(wp.use_count() == 2);}assert(wp.use_count() == 1);sp.reset();assert(wp.expired());assert(!wp.lock());5.bad_weak_ptr微软的TR1提供的一个指针,作为当shared_ptr以一个weak_ptr类对象为参数的构造函数时抛出的一个异常。下面是CSDN的例子:// std_tr1__memory__bad_weak_ptr.cpp // compile with: /EHsc #include <memory> #include <iostream> int main() { std::tr1::weak_ptr<int> wp; { std::tr1::shared_ptr<int> sp(new int); wp = sp; } try { std::tr1::shared_ptr<int> sp1(wp); // weak_ptr has expired } catch (const std::tr1::bad_weak_ptr&) { std::cout << "bad weak pointer" << std::endl; } catch (...) { std::cout << "unknown exception" << std::endl; } return (0); } 6.pool库1).explicit pool(size_t requested_size)构造函数指示每次pool分配内存块的大小(requested_size),pool会根据需要自动地向系统申请或归还使用的内存,在析构时,pool将自动释放它所持有的所有内存块。2).malloc()行为类似C中的malloc(),用void*指针返回从内存池中分配的内存块,大小为构造函数中指定的requested_size。如果内存分配失败,函数返回0,不会抛异常。3).分配后的内存块可以用is_from()函数测试时候从这个内存此分配出去的。下面是书中例子:#include <boost/pool/pool.hpp>using namespace boost;int main(){pool<> pl(sizeof(int));int *p = (int *)p1.malloc();assert(p1.is_from(p));p1.free(p);for (int i = 0; i < 100; ++i) {p1.ordered_malloc(10);		}					}		//内存池对象析构,所有分配的内存在这里都被释放。4).pool<>只需要注意一点,它只能作为普通数据类型入int、double等的内存池,不能应用于复杂的类和对象,因为它只分配内存,不调用析构函数,这个时候我们需要用object_pool。7.object_pool1).object_pool是用于类实例(对象)的内存池,它的功能与pool类似。但会在析构时对所有已经分配的内存块调用析构函数,从而正确地释放资源。模板如下:template<typename ElementType>class object_pool : protected pool{...}2).malloc()和free()函数分别分配和释放一块类型为ElementType*的内存块,但它们被调用时并不调用类的构造函数和析构函数,也就是说操作的是一块原始内存块,里面的值是未定义的,因此我们应尽量少使用。3).construct()和destroy()这两个函数是object_pool真正价值所在。construct先调用malloc()分配内存,然后再在内存块上使用传入的参数调用类的构造函数,返回的是一个已经初始化的对象指针。destroy()则先调用对象的析构函数,然后再用free()释放内存块。下面是书中例子:struct demo_class {public:int a,b,c;demo_class(int x=1, int y=2, int z=3) : a(x), b(y), c(z){}};int main(){object_pool<demo_class> p1;demo_class *p = p1.malloc();assert(p1.is_from(p));//p指示那个内存未经过初始化assert(p->a!=1 || p->b!=2 || p->c!=3);p = p1.construct(7, 8, 9);assert(p->a == 7);object_pool<string> pls;for (int i = 0; i < 10; ++i) {string *ps = pls.construct("hello object_pool");cout<< *ps << endl;}}8.assign1).用于更方便的往STL容器填充数据。使用assign库必须使用using指示符,只有才能让重载的+=,等操作符在作用域内生效。assign仅限应用于STL中定义的标准容器(vector、list、set等)#include <boost/assing.hpp>int main(){using namespace boost::assign;vector<int> v;v += 1,2,3,4,5,6*6;set<string> s;s += "cpp","java","c#","python";map<int, string> m;m += make_pair(1, "one"), make_pair(2, "two");}2).assign提供三个辅助函数insert()、push_front()、push_back()。这些函数可用于拥有同名成员函数的容器,接受容器变量作为参数,返回一个代理对象list_inserter。书中例子:#include <boost/assign.hpp>int main(){using namespace boost::assign;vector<int> v;push_back(v)(1)(2)(3)(4)(5);list<string> l;push_front(1)("c++")("c#")("java")("python");set<double> s;insert(s)(3.14)(0.618)(1.732);map<int, string> m;insert(m)(1, "one")(2, "two");}甚至能写出一些可怕的代码:deque<string> d;push_front(d)() = "c++","c#","python";3).在容器构造的时候就完成数据的填充,这种方式较赋值更为高效,assign使用list_of()、map_list_of()/pair_list_of()和tuple_list_of()三个函数进行这些处理。vector<int> v = list_of(1)(2)(3)(4);set<int> s = (list_of(10), 20, 30);例子中的语法还是比较复杂,我觉得还是尽可能少用比较好。9.singleton1).singleton即单件模式,实现这种模式的类在程序生命周期里只能有一个且仅有一个实例。目前Boost中并没有专门的单件库,而仅是其他库中有并不十分完善的实现。下面介绍singletom_default。template <typename T>struct singleton_default{public:typedef T object_type;static object_type & instance();};singleton_default把模板参数T实现为一个单件类,唯一实例只能通过静态成员函数instance()访问。它运用了巧妙的技术,可以在main()运行之前就创建单件。对类型T的要求是有缺省(无参)构造函数,而且在析构函数时不能抛出异常,因为单件在main()前后构造和析构,如果发生异常会无法捕抓。下面是书中的例子:#include <boost/pool/default/detail/singleton.hpp>using boost::details::pool::singleton_default;class point {public:point(int a=0, int b=0, int c=0):x(a),y(b),z(c){cout<<"point ctor"<<endl;}~point(){cout<<"point dtor"<<endl;}};int main(){cout<<"main() start"<<endl;typedef singleton_default<point> origin;origin::instance().print();cout<<"main() finish"<<endl;}2).另一个单件类boost.serialzation里的singleton。大体跟singleton_default相同,区别是serialzation的但单件实现在访问单件实例的成员函数分为了常对象和可变对象两个函数。这种区分是出于线程安全的考虑,常对象单件总是线程安全的,应为它不会改变内部状态,而可变对象单件则不是线程安全的,可能会发生线程竞争问题。#include <boost/serialization/singleton.hpp>using boost::serialization::singleton;class point{...};int main(){cout<<"main() start"<<endl;typedef singleton<point> origin;origin::get_const_instance().print();	//常对象origin::get_mutable_instance().print();	//可变对象cout<<"main() finish"<<endl;}关于单件模式还搜到些有趣的文章,如:1.ACE vs Boost: Singleton的实现http://hi.baidu.com/okeyes888/blog/item/1db64a356c4d3c95a71e123b.html2.Double-Checked Locking: An Optimization Pattern for Efficiently Initializing and Accessing Thread-safe Objectshttp://www.cs.wustl.edu/~schmidt/PDF/DC-Locking.pdf

这篇关于Boost程序库完全开发指南-读书笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1060040

相关文章

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

SQL Server数据库迁移到MySQL的完整指南

《SQLServer数据库迁移到MySQL的完整指南》在企业应用开发中,数据库迁移是一个常见的需求,随着业务的发展,企业可能会从SQLServer转向MySQL,原因可能是成本、性能、跨平台兼容性等... 目录一、迁移前的准备工作1.1 确定迁移范围1.2 评估兼容性1.3 备份数据二、迁移工具的选择2.1

基于Python开发PPTX压缩工具

《基于Python开发PPTX压缩工具》在日常办公中,PPT文件往往因为图片过大而导致文件体积过大,不便于传输和存储,所以本文将使用Python开发一个PPTX压缩工具,需要的可以了解下... 目录引言全部代码环境准备代码结构代码实现运行结果引言在日常办公中,PPT文件往往因为图片过大而导致文件体积过大,

在 Windows 上安装 DeepSeek 的完整指南(最新推荐)

《在Windows上安装DeepSeek的完整指南(最新推荐)》在Windows上安装DeepSeek的完整指南,包括下载和安装Ollama、下载DeepSeekRXNUMX模型、运行Deep... 目录在www.chinasem.cn Windows 上安装 DeepSeek 的完整指南步骤 1:下载并安装

nginx-rtmp-module构建流媒体直播服务器实战指南

《nginx-rtmp-module构建流媒体直播服务器实战指南》本文主要介绍了nginx-rtmp-module构建流媒体直播服务器实战指南,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录1. RTMP协议介绍与应用RTMP协议的原理RTMP协议的应用RTMP与现代流媒体技术的关系2

Spring Boot统一异常拦截实践指南(最新推荐)

《SpringBoot统一异常拦截实践指南(最新推荐)》本文介绍了SpringBoot中统一异常处理的重要性及实现方案,包括使用`@ControllerAdvice`和`@ExceptionHand... 目录Spring Boot统一异常拦截实践指南一、为什么需要统一异常处理二、核心实现方案1. 基础组件

使用DeepSeek API 结合VSCode提升开发效率

《使用DeepSeekAPI结合VSCode提升开发效率》:本文主要介绍DeepSeekAPI与VisualStudioCode(VSCode)结合使用,以提升软件开发效率,具有一定的参考价值... 目录引言准备工作安装必要的 VSCode 扩展配置 DeepSeek API1. 创建 API 请求文件2.