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

相关文章

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

使用JavaScript将PDF页面中的标注扁平化的操作指南

《使用JavaScript将PDF页面中的标注扁平化的操作指南》扁平化(flatten)操作可以将标注作为矢量图形包含在PDF页面的内容中,使其不可编辑,DynamsoftDocumentViewer... 目录使用Dynamsoft Document Viewer打开一个PDF文件并启用标注添加功能扁平化

电脑显示hdmi无信号怎么办? 电脑显示器无信号的终极解决指南

《电脑显示hdmi无信号怎么办?电脑显示器无信号的终极解决指南》HDMI无信号的问题却让人头疼不已,遇到这种情况该怎么办?针对这种情况,我们可以采取一系列步骤来逐一排查并解决问题,以下是详细的方法... 无论你是试图为笔记本电脑设置多个显示器还是使用外部显示器,都可能会弹出“无HDMI信号”错误。此消息可能

如何安装 Ubuntu 24.04 LTS 桌面版或服务器? Ubuntu安装指南

《如何安装Ubuntu24.04LTS桌面版或服务器?Ubuntu安装指南》对于我们程序员来说,有一个好用的操作系统、好的编程环境也是很重要,如何安装Ubuntu24.04LTS桌面... Ubuntu 24.04 LTS,代号 Noble NumBAT,于 2024 年 4 月 25 日正式发布,引入了众

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

C#图表开发之Chart详解

《C#图表开发之Chart详解》C#中的Chart控件用于开发图表功能,具有Series和ChartArea两个重要属性,Series属性是SeriesCollection类型,包含多个Series对... 目录OverviChina编程ewSeries类总结OverviewC#中,开发图表功能的控件是Char

鸿蒙开发搭建flutter适配的开发环境

《鸿蒙开发搭建flutter适配的开发环境》文章详细介绍了在Windows系统上如何创建和运行鸿蒙Flutter项目,包括使用flutterdoctor检测环境、创建项目、编译HAP包以及在真机上运... 目录环境搭建创建运行项目打包项目总结环境搭建1.安装 DevEco Studio NEXT IDE

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD