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

相关文章

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

Nginx中配置HTTP/2协议的详细指南

《Nginx中配置HTTP/2协议的详细指南》HTTP/2是HTTP协议的下一代版本,旨在提高性能、减少延迟并优化现代网络环境中的通信效率,本文将为大家介绍Nginx配置HTTP/2协议想详细步骤,需... 目录一、HTTP/2 协议概述1.HTTP/22. HTTP/2 的核心特性3. HTTP/2 的优

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

在React中引入Tailwind CSS的完整指南

《在React中引入TailwindCSS的完整指南》在现代前端开发中,使用UI库可以显著提高开发效率,TailwindCSS是一个功能类优先的CSS框架,本文将详细介绍如何在Reac... 目录前言一、Tailwind css 简介二、创建 React 项目使用 Create React App 创建项目

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

Java利用JSONPath操作JSON数据的技术指南

《Java利用JSONPath操作JSON数据的技术指南》JSONPath是一种强大的工具,用于查询和操作JSON数据,类似于SQL的语法,它为处理复杂的JSON数据结构提供了简单且高效... 目录1、简述2、什么是 jsONPath?3、Java 示例3.1 基本查询3.2 过滤查询3.3 递归搜索3.4