当前位置:文档之家› C++ boost库总结(精心整理)

C++ boost库总结(精心整理)

C++ boost库总结(精心整理)
C++ boost库总结(精心整理)

第1章 Boost程序库总论

1.使用Boost,将大大增强C++的功能和表现力

第2章时间与日期

1.timer提供毫秒级的计时精度,内部是通过std::clock取时间的

2.progress_timer自动打印某生命周期的执行时间

3.原则上程序库的代码是不应该被用户修改的

4.progress_display可以在控制台上显示程序的执行进度

5.date_time库能很好的表示日期时间概念,并能和C的时间结构tm进行友好互转

6.date类提供年月日和星期几的概念。data可通过from_string或

from_undelimited_string从字符串解析而来,可通过to_simple_string、

to_iso_string、to_extended_iso_string转换为字符串。(精度到天的DateTime)

7.day_clock是精度到天的时钟

8.date_duration表示的是天精度的时间间隔概念,别名为days,另外还有years、

months、weeks

9.date_period表示两个date之间的日期区间(精度到天的TimeSpan)

10.date_iterator、week_iterator、month_iterator和year_iterator是时间的迭代

11.boost::greorian::gregorian_calendar中有实用静态方法:is_leap_year、

end_of_month_day

12.time_duration表示微妙或纳秒级的时间概念,几个实用子类:hours、minutes、

seconds、millisec/milliseconds、microsec/microseconds、nanosec/nannoseconds

13.duration_from_string可以从字符串解析time_duration

14.ptime用来表示时间点,相当于date和time_duration的组合。可以用

time_from_string或from_iso_string解析。(TimeSpan)

ptime now1 = second_clock::local_time(); // 得到本地当前秒精度时间

ptime now2 = microsec_clock::universal_time(); // 得到本地当前微秒精度时

15.time_period表示两个ptime之间的时间区间。(DateTime)

16.时间迭代器没有日期迭代器那么多,只有time_iterator一个

17.(boost时间日期库乱、破碎、过度设计)

第3章内存管理

1.scoped_ptr类似auto_ptr,但其一旦获得对象的管理权,你就无法再从它那里取回

来。该智能指针只希望在本作用域里使用,不希望被转让。auto_ptr有意设计成所

有权的自动转让,scoped_ptr有意设计成所有权的无法转让。scoped_ptr和

auto_ptr均不能作为容器元素。

2.scoped_array包装的是new[]产生的指针,并调用的是delete[]。往往是用来和C

代码保持兼容,一般不推荐使用

3.无论是编译器还是程序员都很难区分出new[]和new分配的空间,错误的运用delete

将导致资源异常

4.在C++历史上曾经出现过无数的引用计数型智能指针实现,但没有一个比得上

boost::shared_ptr,在过去、现在和将来,它都是最好的

5.shared_ptr支持的转型有:static_pointer_cast、const_pointer_cast

dynamic_pointer_cast,返回的结果是shared_ptr,并能保证这些指针的引用计数正确

6.用shared_ptr可以消除代码中显示的delete,用make_shared、allocate_shared

可以消除代码中显示的new

7.桥接模式(bridge)是一种结构型设计模式,它把类的具体实现细节对用户隐藏起来,

以达到类之间的最小耦合关系。在具体编程实践中桥接模式也被称为pimpl或者handle/body惯用法,它可以将头文件的依赖关系降到最小,减少编译时间,而且可以不使用虚函数实现多态

8.get_deleter(shared_ptr const& p)可以获得删除器。shared_ptr的删除器在

处理某些特殊资源时非常有用,它使得用户可以定制、扩展shared_ptr的行为,使其不仅仅能够管理内存资源,而是称为一个“万能”的资源管理工具

9.对应shared_ptr,也有一个shared_array,scoped_array和shared_array均不对

operator[]做下标检测

10.weak_ptr是为配合shared_ptr而引入的,更像是shared_ptr的一个助手而不是智

能指针,其没有重载operator*和->,不具有普通指针的行为。它最大的作用在于协助shared_ptr工作,像旁观者那样观测资源的使用情况

11.weak_ptr被设计为与shared_ptr共同工作,可以从一个shared_ptr或者另一个

weak_ptr对象构造,获得资源的观测权。但weak_ptr没有共享资源,它的构造不会引起指针引用计数的增加。同样,在weak_ptr析构时也不会导致引用计数的减少,它只是一个静静的观察者

12.获得this指针的shared_ptr,使对象自己能够产生shared_ptr管理自己:class T :

public enable_shared_from_this, then shared_ptr shared_from_this(). 13.intrusive_ptr是一个侵入式的引用计数型指针。当对内存占用的要求非常严格,

或现存代码已经有了引用计数机制时可以考虑。一般情况不推荐使用。

14.pool为固定块大小的类似malloc的原生内存分配器,支持数组式分配,一般情况

下不必对分配的内存调用free()。只分配原生内存,不调用构造函数,回收不调用析构函数,最好不要用于对象。

15.singleton_pool和pool接口完全一致,但为单件线程安全,同样要求编译期指定

要分配的原生内存块大小

16.object_pool为特定类型的对象池,不支持数组式分配,支持对象分配和对象原生

内存分配

17.pool_alloc和fast_pool_allocator是boost提供的两个STL分配器。除非有特别

需求,我们应该总使用STL实现自带的内存分配器。使用定制的分配器需要经过仔细的测试,以保证它与容器可以共同工作。

18.内存管理是C++程序开发中永恒的话题,因为没有GC,小心谨慎的管理内存等系统

资源是每一个C++程序员都必须面对的问题

第4章实用工具

1.private继承自noncopyable可以编译时禁止对象拷贝语法

2.C++静态强类型的优点有时候反而是阻碍程序员生产力的“缺陷”

3.typeof库使用宏模拟了C++0X中的typedef和auto关键字,可以减轻书写繁琐的

变量类型声明工作,简化代码。对于用户自定义类型需要手工用宏注册。(语法并没那么好看,不准备使用)

4.optional使用“容器”语义,包装了“可能产生无效值”的对象,实现了“未初

始化”的概念(Nullable

5.optional make_optional(bool condition, T const& v)用来简单构建optional

对象,但不能处理optional的情况。(此乃鸡肋)

6.optional str(in_place("string就地创建")),而不需拷贝临时对象,避

免大对象的拷贝开销

7.用于初始化的assign库(仅限于STL标准容器,通过重载“+=”和“,”运算符实

现):

#include

using namespace boost;

vector v; v += 1,2,3,4,5,6*6;

set s; s += "cpp", "java";

map m; m += make_pair(1, "one"), make_pair(2, "2");

8.assign还支持insert()、push_front()、push_back()(通过重载“()”实现):

vector v; push_back(v)(1)(2)(3)(4)(5);

list l; push_front(l)("cpp")("java");

set s; insert(s)(3.14)(0.618)(1.732);

map m; insert(m)(1, "one")(2, "two");

9.assign也可以将“()”和“,”混用:

vector v;

push_back(v), 1, 2, 3, 4, 5;

push_back(v)(6), 7, 64 / 8, (9), 10;

deque d;

push_front(d)() = "cpp", "java";

10.assign list_of()函数:

vector v = list_of(1)(2)(3);

deque d = (list_of("cpp")("java"));

set s = (list_of(10), 20, 30, 40);

map m = list_of(make_pair(1, "one")) (make_pair(2, "two")) 如果需要将括号与逗号混合使用,则要求最外侧加一个括号,否则编译器无法推导11.assign map_list_of/pair_list_of函数:

map m1 = map_list_of(1, 2)(3, 4)(5, 6)

map m2 = map_list_of(1, "one")(2, "two")

12.assign tuple_list_of用户初始化元素类型为tuple的容器

13.assign repeat()可以重复生成值,repeat_fun()可以重复无参函数或仿函数,

range()则可以从序列中取出部分或全部:

vector v = list_of(1).repeat(3, 2)(3)(4)(5); // v = 1,2,2,2,3,4,5 multiset ms; insert(ms).repeat_fun(5, &ran).repeat(2, 1), 10; // ms = x,x,x,x,x,1,1,10

deque d; push_front(d).range(v.begin(), v.begin() + 5); // d=3,2,2,2,1 14.assign支持8个STL标准容器(vector、string、deque、list、set、multiset、

map、multimap),对容器适配器(stack、queue、priority_queue)则需要通过to_adapter():

stack stk = (list_of(1), 2, 3).to_adapter();

queue q = (list_of("cpp")("java")).repeat(2, "C#").to_adapter();

priority_queue pq = (list_of(1.414), 1.732).to_adapter();

15.assign也支持部分不在STL中的非标准容器slist、hash_map、hash_set,因为其

符合标准容器定义,同时也支持大部分boost容器:array、circular_buffer、unordered等

16.assign list_of()嵌套:

vector> v = list_of(list_of(1)(2)) list_of(list_of(3)(4));

v += list_of(5)(6), list_of(7)(8);

17.assign ref_list_of()、cref_list_of()、ptr_push_back()、ptr_list_of()还支

持以引用或指针来构造初始化:

int a = 1, b = 2, c = 3;

vector v = ref_list_of<3>(a)(b)(c);

18.boost::swap是对std::swap的增强,并且扩充了对数组的支持:

int a1[10]; std::fill_n(a1, 10, 5);

int a2[10]; std::file_n(a2, 10, 20);

boost::swap(a1, a2);

19.单件boost::details::pool::singleton_default在main之前进行构造,支持

继承或非继承形式(最恨main之前的事情了)

20.单件boost::serialization::singleton在main之前进行构造,支持继承或非

继承形式。继承方式更彻底一些,非继承方式不影响原有代码

21.boost::tribool三态bool,indeterminate(tribool)可判断一个三态bool是否处

于不确定状态

22.选择optional还是tribool:如果返回值可能是无效的,那么就是

optional,如果返回值总是确定的,但可能无法确定其意义,那么就用

tribool(最多自己随手定义个enum状态,为了这点需求需要记住这一堆名称和细节!)

https://www.doczj.com/doc/9b3856079.html,ing namespace std::rel_ops; 则一旦为类定义了operator==和<,则自动具

有!=、>、<=和>=的功能。boost operators库提供了对该功能的增强,使用时只需继承自这些类并提供指定的operator重载即可获得附送的重载:

1.equality_comparable:要求提供==,可自动实现!=,相等语义

2.less_than_comparable:要求提供<,可自动实现>、<=、>=

3.addable:要求提供+=,可自动实现+

4.subtractable:要求提供-=,可自动实现-

5.incrementable:要求提供前置++,可自动实现后置++

6.decrementable:要求提供前置--,可自动实现后置--

7.equivalent:要求提供<,可自动实现==,等价语义

8.totally_ordered:全序概念,组合了equality_comparable和

less_than_comparable

9.additive:可加减概念,组合了addable和subtractable

10.multiplicative:可乘除概念,组合了multipliable和diviable

11.arithmetic:算术运算概念,组合了additive和multiplicative

12.unit_stoppable:可步进概念,组合了incrementable和decrementable

13.public dereferenceable:解引用操作符,要求提供operator*,

可自动实现operator->。P为operator->返回类型,一般为T*

14.public indexable:下标操作符,I为下标类型,要求能够

与类型T做加法操作,通常为int;R是operator[]的返回值类型,通常是

一个类型的引用。要求提供operator+(T, I),将自动实现operator[]

1.如果只关心类的等价语义,那么就用equivalent,如果想要精确的比较两个对象的

值,就是用equality_comprable。相等equivalent基于"=="实现,而

equality_comprable基于"<"的"!(xy)"实现。

2.应该总对异常类是用虚继承

3.struct my_exception :

virtual std::exception, // 兼容C++标准异常

virtual boost::exception

{};

typedef boost::error_info err_no;

typedef boost::error_info err_str;

#include

try { throw my_exception() << err_no(10); }

catch(my_exception& e)

{

cout << *get_error_info(e) << endl;

cout << e.what() << endl;

e << err_str("向异常追加信息,还可再次抛出");

cout << *get_error_info(e) << endl;

}

4.从exception派生的异常定义非常简单,没有实现代码,可以很容易建立起一个适

合自己程序的、惊喜完整的异常类体系。只要都是用虚继承,类体系可以任意复杂。

5.boost库预定义的异常类型:

typedef error_info

errinfo_api_function;

typedef error_info errinfo_at_line;

typedef error_info>

errinfo_file_handle;

typedef error_info

errinfo_file_name;

typedef error_info

errinfo_file_open_mode;

typedef error_info

error_info_type_info_name;

typedef error_info throw_function;

typedef error_info throw_file;

typedef error_info throw_line;

6.enable_error_info(T& e),可以将已将存在的任意类型包装为boost异常类型

7.throw_exception(任意异常类型),可以自动将任意异常类型包装为boost异常,还

能保证线程安全

8.diagnostic_information(e)可以得到任意boost异常的字符串内容描述;在catch

块中调用current_exception_diagnostic_information(),则不用传参数e。(何

必呢,为少写一两个字母反而要记住一个更长的名字)

9.catch块内的异常转型用current_exception_cast()

10.catch块内调current_exception()得到当前异常指针的exception_ptr是线程安全

的,rethrow_exception可以重新抛出异常

11.UUID, Universally Unique Identifier, 128bit(16 Byte),不需要中央认证机构

就可以创建全球唯一的标识符。别名GUID

12.不是所有的警告都可以忽略的,有的警告预示着可能潜在的错误

13.BOOST_BINARY(111 00 1),可以实现编译器的二进制定义,但不能超过8bit

第5章字符串与文本处理

1.lexical_cast(X),可以实现字符串和数值类型之间的转换,但不支持高级格式

控制。转换失败将抛出bad_lexical_cast异常。lexical_cast底层用C++流实现,要求目标类型支持operator<<、operator>>、无参构造函数和拷贝构造函数

2.cout << format("%s:%d+%d=%d\n") %"sum" %1 %2 %(1+2); // sum:1+2=3

format fmt("(%1%+ %2%) * %2%= %3%\n");

fmt %2 %5;

fmt %((2+5)*5);

cout << fmt.str(); // (2 + 5) * 5 = 35

3.format在提供的参数过多或过少的情况下operator<<或str()都会抛出异常

4.format完全支持printf的格式化选项方式,同时还增加了新的方式:

1.%|spec|%:与printf格式选项功能相同,但两边增加了竖线分隔,可以更

好的区分格式化选项有普通字符

2.%N%:标记第N个参数,相当于占位符,不带任何其他的格式化选项

1.format因为做了很多安全检查工作,会比printf慢至少2-5倍

2.format相关的高级功能:

1.basic_format& bind_arg(int argN, const T& val) 把格式化字符串第

argN位置的输入参数固定为val,即使调用clear()也保持不变,除非调用

clear_bind()或clear_binds()

2.basic_format& clear_bind(int argN) 取消格式化字符串第argN位置的

参数绑定

3.basic_format& clear_binds()

4.basic_format& modify_item(int itemN, T manipulator) 设置格式化字符

串第itemN位置的格式化选项,manipulator是一个boost::io::group()

返回的对象

5.boost::io::group(T1 a1, ..., Var const& var) 是一个最多支持10个参

数的模板函数,可以设置IO流操纵器以指定格式或输入参数值

1.string_algo库包括:

1.to_upper, to_lower, starts_with, ends_with, contains, equals,

lexicographical_compare

2.all(检测字符串中的所有元素是否满足给定的判断式)

3.仿函数is_equal, is_less, is_not_greater

4.is_space, is_alnum, is_alpha, is_cntrl, is_digit(十进制数字),

is_graph, is_lower, is_print, is_punct(是否是标点符号), is_upper,

is_xdigit(字符是否为十六进制数字), is_any_of(字符是否是参数字符序

列中的任意数字), if_from_range(字符是否位于指定的区间[c1,c2]内)

5.trim_left、trim_right、trim

6.find_first、find_last、find_nth、find_head、find_tail

7.replace/erase_first、replace/erase_last、replace/erase_nth、

replace/erase_all、replace/erase_head、replace/erase_tail

8.find_all、split、find_iterator、split_iterator、join

1.tokenizer类似string_algo::split,为更专业的token划分工具。tokenizer库

提供预定义好的四个分词对象:

1.char_delimiter_separator:使用标点符号分词,是默认的分词函数对象。

已被声明废弃

2.char_separator:支持一个字符集合作为分隔符,默认行为与

char_delimiter_separator类似

3.escaped_list_separator:用于CSV格式的分词

4.offset_separator:使用偏移量来分词

2.xpressive,类似boost.regex的正则表达式解析器,同时还是一个类似于

boost.spirit的语法分析器,并且将这两种完全不相交的文本处理方式完美的融合在了一起

3.xpressive使用regex_token_iterator<>提供了强大的分词迭代器

第6章正确性测试

1.测试对于软件开发是非常重要的,程序员——尤其是C++程序员更应该认识到这一

2.BOOST_ASSERT宏类似于assert宏,提供运行时断言,但功能有所增强。可以通过

BOOST_DISABLE_ASSERTS来关闭。当定义BOOST_ENABLE_ASSERT_HANDLER后,断言

触发时将会调用boost::assertion_failed回调

3.BOOST_VERIFY类似BOOST_ASSERT,但断言表达式一定会被求值,Release下仍然会

失效(放弃BOOST_VERIFY)

4.BOOST_STATIC_ASSERT,编译时断言。可以出现在程序的任何位置,而不一定只在函

数域内

5.测试用例是一个包含多个测试断言的函数,它是可以被独立执行测试的最小单元,

各个测试用例之间是无关的,发生的错误不会影响到其他测试用例

第7章容器与数据结构

1.array是的C原生数组的STL接口包装

2.std::vector是vector对bool的特化,内部保存的实际为bit,支持动态长

度。std::bitset大小固定,但支持更多的位运算

3.boost.dynamic_bitset类似std::vector可以动态长度,同时提供了丰富的

位运算。dynamic_bitset还支持集合相关操作

4.哈希容器:boost::unordered_map、boost::unordered_set、

boost::unordered_multimap、boost::unordered_multiset

5.boost::bimap,双向映射容器,提供left、right两个试图。支持的集合类型有:

set_of、multiset_of、unordered_set_of、unordered_multiset_of、list_of、

vector_of、unconstrained_set_of

6.bimap的左右视图还可以通过标签访问:

bimap, tagged> bm;

bm.by().insert(make_pair(1, "C++")); // 相当于使用左视图

bm.by().insert(make_pair("java", 2)); // 相当于使用右视图

7.circular_buffer为大小固定的循环缓冲区,

circular_buffer_space_optimized类似circular_buffer但只在确实需要

时才分配内存,并且当容器内元素减少时自动释放内存

8.tuple是固定数目非同质元素容器。tuple是std::pair的泛化,可以从函数返回任

意数量的值,也可以代替struct组合数据

9.和std::make_pair对应,也有个make_tuple用来简化tuple的创建

10.tie()可以生成一个元素类型全是引用的tuple,相当于make_tuple(ref(a),

ref(b), ...),可以用于左值,通常用来接收返回tuple或pair函数的返回值,可以看成是对tuple的解包

11.element::type可以给出T中第N个元素的类型,length::value可以给

出T的元素数量

12.any能够容纳任意类型,可以用any_cast(a)类型安全的取出any中的值(让人

联想到Ogre::Any)

13.any可以持有原始指针,但这样的用法很不安全,会导致内存泄露。应该使用智能

指针包装原始指针,这样在any析构时智能指针会自动的调用delete,从而安全的释放资源

14.如果希望一种数据结构具有tuple那样的容纳任意类型的能力,又可以在运行时动

态变化大小,那么就可以用any作为元素类型搭配容器

15.variant是对C/C++中union概念的增强和扩展。varinat是有界类型,元素类型范

围由用户指定,any是无界类型,可以容纳任意类型

16.multi_array,相当于int ma[X][Y][Z]的多维数组。multi_array没有异

常机制来处理错误,保证数组范围不越界是库用户自己的责任

17.property_tree是一个保存了多个属性值的树形数据结构,可以用类似路径的简单

方式访问任意节点的树形,而且每个节点都可以用类似STL的风格遍历子节点。

property_tree特别适合于应用程序的配置数据处理,可以解析xml、ini、json和info四种格式的文本数据,使用它能减轻自己开发配置管理的工作。

第8章算法

1.boost foreach库提供BOOST_FOREACH和BOOST_REVERSE_FOREACH来实现对容器的

正向和反向遍历

2.minmax(a, b)可在一次处理中同时获得最大最小值,执行效率上有很大提高(有提

前优化的感觉了)

3.minmax_element算法族可以得到迭代器区间内的最大最小值

第9章数学与数字

1.从纯数学的角度看,程序也不过是一个非常大的整数而已

2.integer_traits : public std::numeric_limits,提供各种整数类型的编译期最大

最小值

3.基于C99标准中的,定义了各种标准的整数

4.功能类似,用模板类而不是typedef

提供各种整数类型定义

5.boost.rational表示有理数(分数),rational_cast可以将有理数转换为普通

数字

6.最大公约数gcd();最小公倍数lcm()

7.crc_optimal以字节为单位的快速CRC计算,实际常用的是crc_32_type的预定义

算法

8.boost random库提供了26个伪随机数发生器

9.random库提供的随机数分布器:

1.uniform_smallint:在小整数域内的均匀分布

2.uniform_int:在整数域上的均匀分布

3.uniform_01:在区间[0,1]上的实数连续均匀分布

4.uniform_real:在区间[min,max]上的实数连续均匀分布

5.bernoulli_distribution:伯努利分布

6.binomial_distribution:二项分布

7.cauchy_distribution:柯西(洛伦兹)分布

8.gamma_distribution:伽马分布

9.poisson_distribution:泊松分布

10.geometric_distribution:几何分布

11.triangle_distribution:三角分布

12.exponential_distribution:指数分布

13.normal_distribution:正态分布

14.lognormal_distribution:对数正态分布

15.uniform_on_sphere:球面均匀分布

1.variate_generator变量发生器,用于组合随机数发生器和

分布器

2.真随机数无法用纯软件产生,因为计算机本身是个确定的有限状态自动机

第10章操作系统相关

1.io_state_savers库可以简化恢复流状态的工作,它能够保存流的当前状态,自动

恢复流的状态或者由程序员控制恢复的时机

1.基本的标准属性保存器:ios_flags_saver、ios_width_saver

2.增强的标准属性保存器:ios_iostate_saver、ios_rdbuf_saver

3.自定义的属性保存器:ios_iword_saver、ios_pword_saver

4.组合的属性保存器:ios_all_saver

1.system库使用轻量级的对象封装了操作系统底层的错误代码和错误信息,使调用操

作系统功能的程序可以被很容易的移植到其他操作系统

filesystem库中的path和wpath提供了文件路径相关的很多实用操作(类似Path)

2.portable_posix_name()和windows_name()分别检测文教案名字符串是否符合

POSIX和Windows规范。Windows的文件名可以字符范围比POSIX的大。

3.native()判断文件名是否符合本地文件系统命名规则

4.为了程序的健壮性,应总使用try-catch来保护文件访问代码

5.directory_iterator和wdirectory_iterator提供了迭代一个目录下所有文件的功

6.recursive_directory_iterator和wrecursive_directory_iterator提供递归遍历

目录功能

7.program_options库提供了强大的命令行参数处理功能,它不仅能够分析命令行,

也能够从配置文件甚至环境变量中获取参数,实现了非常完善的程序配置选项处理

功能

8.#include

using namespace boost::program_options;

int main(int argc, char* argv[])

{

options_description opts("demo options");

opts.add_options()

("help", "just a help info")

("filename", value(), "to find a file");

variables_map vm;

store(parse_command_line(argc, argv, opts), vm);

// 解析完成,实现选项处理逻辑

if(vm.count("help"))

{

cout << opts << endl;

return 0;

}

if(vm.count("filename"))

{ cout << "find" << vm["filename"].as() << endl; }

if(vm.size() == 0)

{ cout << "no options" << endl; }

}

9.program_options库的解析程序选项功能由三个基本组件构成,分别是选项描述器、

分析器和存储器。选项描述其定义选项及选项的值,分析器依据选项描述器的定义

解析命令行或数据文件,存储器则把分析器的结果保存起来以供使用

第11章函数与回调

1.result_of::type确定一个调用表达式的返回类型,是实现泛型库

的底层基本构件

2.ref()和cref()可以包装对象的引用,在传递参数时消除对象拷贝的代价,或者将

不可拷贝的对象变为可以拷贝

3.bind是对标准库bind1st、bind2nd的泛化和增强,可以适配任意的可调用对象。

4.bind第一个参数必须是一个可调用对象,包括函数、函数指针、函数对象和成员函

数指针

5.bind也可以绑定到public成员变量,用法与绑定成员函数类似,只需要把成员变

量名像一个成员函数一样去使用

6.bind绑定到仿函数时,要求仿函数typedef xxx result_type;否则就只能用

bind(functor())的形式

7.bind重载了比较操作符和逻辑非操作符,可以把多个bind绑定式组合起来,形成

一个复杂的逻辑表达式,配合标准库算法可以实现语法简单但语义复杂的操作:

using namespace boost::assign;

typedef rational ri; // 有理数类

vector v = list_of((ri(1, 2)) (ri(3, 4)) (ri(5, 6))); // 初始化

// 删除所有分子为1的有理数

remove_if(v.begin(), b.end(), bind(&ri::numerator, _1) == 1);

assert(v[0].numerator() == 3); // 有理数1/2被删除

// 使用find_if算法查找分子是1的有理数,不不存在

assert(find_if(v.begin(), b.end(), bind(&ri::numerator, _1) == 1) ==

v.end());

// 查找分子大于3且分母小于8的有理数

BOOST_AUTO(pos, find_if(v.begin(), b.end(), bind(&ri::numerator, _1) > 3 && bind(&ri::denominator, _1) < 8));

cout << *pos << endl; // 输出5/6

8.变长参数函数、__stdcall、__fastcall、extern "C"等函数bind时需要显式指定

返回值类型才行

9.function是一个函数对象的“容器”,概念上像是C/C++中的函数指针类型的泛化,

是一种“智能函数指针”

10.调用空的function将抛出bad_function_call异常,最好在使用前通过empty()来

测试有效性

11.与原始的函数指针相比,function对象的体积要稍微大一点(3个指针的大小),

速度要稍微慢一点(10%左右的性能差距),但这与它带给程序的巨大好处相比是无足轻重的

12.signals2基于boost中的另一个库signals,实现了线程安全的观察者模式。在

signals2库中,观察者模式被称为信号/插槽(sinals and slots),它是一种函数

回调机制,一个信号关联了多个插槽,当信号发出时,所有关联它的插槽都会被调

13.signal是不可拷贝的,如果把signal作为自定义类的成员变量,那么自定义类也

将是不可拷贝的,除非用shared_ptr来包装

14.signal.connection()连接插槽时,会返回一个connection对象,可以用来管理信

号和插槽之间的连接关系

15.signal2库使用slot类提供了自动连接管理的功能,能够自动跟踪插槽的生命周期,

但插槽失效时会自动断开连接

16.较之signals,signals2具有线程安全,能够用于多线程环境,而且不需要编译就

可以使用

第12章并发编程

1.thread库提供的互斥量:

1.mutex:独占式互斥量

2.timed_mutex:提供超时锁定功能的独占式互斥量

3.recursive_mutex:递归式互斥量,可以多次锁定,相应的也要多次解锁

4.recursive_timed_mutex:提供超时锁定功能的递归式互斥量

5.shared_mutex:multiple-reader/single-writer型的共享互斥量(读写锁)

1.scoped_lock和scoped_try_lock可以在退出作用域时确保unlock的调用

2.提供了一个原子计数器——atomic_count,使用

long进行线程安全的递增递减计数

3.信号量:condition_variable_any和condition_variable

4.thread_group提供一个简单的线程池,可以对一组线程统一操作

5.thread库使用future范式提供异步操作线程返回值的方法,因为这个返回值在线

程开始执行时开始不可用的,是一个“未来”的“期望值”,所以被称为future(期货)。future使用packaged_task和promise两个模板类来包装异步调用,用

unique_future和shared_future来获取异步调用的结果

int fab(int n) // 递归计算斐波那契数列

{

if(n == 0 || n == 1) return 1;

return fab(n - 1) + fab(n - 2);

}

int main()

{

packaged_task pt(bind(fab, 10)); // 声明packaged_task对象,用模板参数指明返回值的类型,packaged_task只接受无参函数,因此需要使用bind unique_future uf = pt.get_future(); // 声明unique_future对象,接受packaged_task的future值,同样要用模板参数指明返回值类型

thread(boost::move(pt)); // 启动线程计算,必须使用boost::move()来转移packaged_task对象,因为packaged_task是不可拷贝的

uf.wait(); // unique_future等待计算结果

assert(uf.is_ready() && uf.has_value());

cout << uf.get() << endl; // 输出计算结果89

}

6.为了支持多个future对象的使用,future还提供wait_for_any()和wait_for_all()

两个自由函数,他们可以阻塞等待多个future对象,知道任意一个或者所有future 对象都可用(is_ready())

7.packaged_task通过包装函数获得异步调用返回值,而promise通过包装函数输出

参数获得返回值。在线程中用set_value()设置promise返回值,用get_future()获得值

void fab2(int n, promise* p) { p->set_value(fab(n)); }

int main()

{

promise p; // promise变量

unique_future uf = p.get_future(); // 赋值future对象

thread(fab2, 10, &p); // 启动计算线程

uf.wait(); // 等待future计算结果

cout << uf.get() << endl;

}

8.thread库提供了两个自由函数lock()和try_lock(),可以一次锁定多个互斥量,

并且不会出现死锁

lock(mu1, mu2);

...;

mu1.unlock(); // 逐个解锁

mu2.unlock();

9.多线程仅执行一次初始化需要使用一个once_flag对象,并把它初始化为

BOOST_ONCE_INIT,然后使用call_once()来调用初始化函数,完成仅执行一次的初始化

once_flag of = BOOST_ONCE_INIT; // 一次初始化标志

void call_func() { call_once(of, init_count); } // 执行一次初始化

int main()

{

(thread(call_func)); // 必须用括号括住临时对象,否则编译器会认为这是个空thread对象声明

(thread(call_func));

this_thead::sleep(posix_time::seconds(1)); // 等待1秒钟}

10.barrier(护栏)可用于多个线程同步,当线程执行到barrier时必须等待,直到所

有的线程都达到这个点时才能继续执行。

11.thread_specific_ptr实现可移植的线程本地存储机制(thread local storage, TLS)

或线程专有存储(thread specific storage, TSS),可以简化多线程应用,提高性能

void printing()

{

thread_specific_ptr pi; // 线程本地存储一个整数

pi.reset(new int()); // 直接用reset()函数赋值

++(*pi); // 递增

mutex::scoped_lock lock(io_mu); // 锁定io流操作

cout << "thread v=" << *pi << endl;

}

12.this_thread名字空间下提供了at_thread_exit(func),允许注册一个线程结束回

调,无论线程是否被中断。但线程意外终止的情况下,该回调不会被执行

13.promise和packaged_task都支持回调函数,可以让future延后在需要的时候获得

值,而不必主动启动线程计算

14.asio库基于OS提供的异步机制,采用前摄器设计模式(Proactor)实现了可移植

的异步或同步IO操作,而且并不要求使用多线程和锁。目前asio主要关注与网络通信方面,支持TCP、ICMP、UDP等网络通信协议,还支持串口读写、定时器、SSL 等功能。asio是一个很好的富有弹性的框架,可以扩展到其他有异步操作需要的领域。

15.asio库基于前摄器模式(Proactor)封装了OS的select、poll/epoll、kqueue、

overlapped I/O等机制,实现了异步IO模型。它的核心类是io_service,相当于前摄器模式中的Proactor角色,asio的任何操作都需要有io_service的参数与。

1.在同步模式下,程序发起一个IO操作,向io_service提交请求,io_service

把操作转交给OS,同步的等待。当IO操作完成时,OS通知io_service,

然后io_service再把结果发回给程序,完成整个同步流程。

2.异步模式下,程序出了要发起IO操作,还要定义一个用于回调的完成处理

函数。io_service同样把IO操作转交给操作系统执行,但它不同步等待,

而是立即返回。调用io_service的run()成员函数可以等待异步操作完成,

当异步操作完成时io_service从OS获取操作结果,调用完成处理函数

3.asio不直接使用OS提供的线程,而是定义了strand以保证在多线程环境

中无需使用互斥量。io_service::strand::wrap()可以包装一个函数在

strand中执行

4.asio提供了mutable_buffer和const_buffer两种可安全用于异步读写的

缓冲区

1.ip::address表示IP地址,可以同时支持ipv4和ipv6两种地址

2.ip::tcp::endpoint表示ip地址和端口号

3.同步socket示例:

1.Server:

int main()

{

try

{

cout << "server start" << endl;

io_service ios; // asio程序必需的io_service对象

ip::tcp::acceptor acceptor(ios,

ip::tcp::endpoint(ip::tcp::v4(), 6688);

cout << acceptor.local_endpoint().address() << end;

while(true)

{

ip::tcp::socket sock(ios);

acceptor.accept(sock); // 阻塞等待socket连接

cout << "client:" << sock.remote_endpoint().address() << endl;

sock.write_some(buffer("hello asio")); // 发送数据。不能直接把数组、vector等容器用做asio的读写参数,必须通过buffer()

函数包装

}

}

catch(std::exception& e) { cout << e.what() << endl; } }

2.Client:

void client(io_service& ios)

{

try

{

cout << "client start" << endl;

ip::tcp::socket sock(ios); // 创建socket对象

ip::tcp::endpoint

ep(ip::address::from_string("127.0.0.1"), 6688); // 创建连接端点

sock.connect(ep);

vector str(100, 0);

sock.read_some(buffer(str)); // 使用buffer包装缓冲区接收数据

cout << "receive from " << sock.remote_endpoint().address() << &str[0] << endl;

}

catch(std::exception& e) { cout << e.what() << endl; }

}

int main()

{

io_service ios;

a_timer at(ios, 5, bind(client, ref(ios))); // 启动定时器

ios.run();

}

1.通常客户端不需要异步通信

2.resolver可实现域名解析

3.interprocess可以处理进程间通信(IPC)

第13章编程语言支持

1.任何程序开发语言都不可能独当一面、包打天下,总有它的长处与短处

2.python库能够在C++中调用Python语言,但它更重要的功能在于用C++编写Python

扩展模块,嵌入到Python解释器中调用,提高Python的执行效率

3.C++中的构造函数不同于普通的成员函数,不能取其地址

第14章其他Boost组件

1.regex:需要编译才能使用的正则库

2.sprit:面向对象的递归下降解析器生成框架,使用EBNF语法

3.gil:有Adobe赞助开发的通用图像库。为像素、色彩、通道等图像处理概念提供了

泛型的、STL式的容器和算法,可以对图像做灰度化、梯度、均值、选装等运算。

支持jpg、png、tiff等格式

4.graph:处理离散数学中的图结构,并提供图、矩阵等数据结构上的泛型算法。可以

看做是STL在非线性容器领域的扩展。

5.intrusive:侵入式容器。STL为非侵入式容器,不需要对容器内的元素类型做修改

即可容纳

6.pointer container:提供了与STL类似的若干种指针容器,性能较好且异常安全。

用STL+shared_ptr也可以做变通。

7.multi_index:实现具有多个STL兼容访问接口(索引)的容器

8.iterators:定义一组基于STL的新迭代器概念、构造框架和游泳的适配器,能够用

来更轻松的实现迭代器模式

9.range:基于STL迭代器提出的“范围”概念,是一个容器的半开区间,使用range

可以让代码更加简单漂亮

https://www.doczj.com/doc/9b3856079.html,mbda:引入lambda表达式和函数式编程,可以就地创建小型的函数对象,避免函

数定义离调用点太远,更方便代码维护。lambda表达式是一种新的编程范式,但其语法十分复杂,如果使用的不好很容易写出过于晦涩难懂的代码,使程序难以维护。

11.signals:观察者模式。功能和用法与signals2基本相同,非线程安全,需要编译。

如果没有什么特殊理由,应该使用signals2库

12.enable_if:允许模板函数或者模板类在偏特化时仅针对某些特定类型有效,依赖于

SFINAE(substitution failure is not an error)原则

13.call_traits:封装了可能是最好的传递参数给函数的方式,它会自动推导出最高效

的传递参数传递类型

14.type_traits:提供一组trait类,用以在编译器确定类型是否具有某些特征。使用

type_traits可以编写出更好更高效的泛型代码

15.concept check:编译器检查模板函数或模板类的模板参数是否符合某个概念,是否

运行进行模板参数推演。主要用来编写泛型算法或实现泛型库

16.function_types:提供对函数、函数指针、函数引用和成员指针等类型进行分类、

分解和合并的功能

17.in_place_factory:直接构造对象而不需要一个临时对象的拷贝

18.proto:允许在C++中构建专用领域嵌入式语言,基于表达式模板技术定义小型专用

语言的“编译器”

19.property map:提供key-value映射的属性概念定义

20.fusion:提供基于tuple的容器和算法,是模板元编程的强大工具,可以与mpl很

好的协同工作

21.mpl:模板元编程框架,包含有编译期的算法、容器和函数等完整的元编程工具。运

用mpl,很多运行时的工作都可以在编译期完成,甚至编译结束就意味着程序的运行结束

22.preprocessor:预处理元编程工具,类似于模板元编程,但发生在编译之前的预处

理阶段。preprocessor改变了以往人们对预处理器的看法,令人们认识到预处理也是一种强大的编程工具。preprocessor可以和模板元编程很好的配合,从而发挥更大的作用

23.interporcess:可移植的进程间通信(IPC)功能,包括共享内存、内存映射文件、

信号量、文件锁、消息队列等现代操作系统的IPC机制,并提供了简洁易用的STL 风格接口,大大简化了IPC编程工作

24.MPI:高性能分布式并行计算应用开发,封装了标准的MPI(消息传递接口)以更好

的支持现代C++编程风格。需要有底层MPI实现的支持,如Open MPI、MPICH等

25.accumulators:用于增量统计的库,也是一个用于增量计算的可扩展的累加器框架,

可以看做是std::accumulate算法的扩展

26.interval:处理“区间”相关的数学问题,把一般的算术运算和集合运算扩展到区

间上

27.math:包含大量数学领域的模板类和算法,如复数的反三角函数、最大公约数和最

小公倍数、四元数、八元数、拉格朗日多项式、椭圆积分、X方分布、伯努利分布

28.uBLAS:用于线性代数的数学库,优于std::valarray。STL风格,容易使用并且效

率很高

29.iostreams:扩展C++标准库流处理的框架。定义了Source、Sink、Filter等流处

理概念,使得编写流处理更容易

30.serialization:实现C++数据结构的持久化,可以把任意的C++对象序列化为字节

流或文本。并且支持STL容器

https://www.doczj.com/doc/9b3856079.html,pressed_pair:与std::pair类似,使用空基类优化技术。当两个成员之一是空

类,则编译器就会“压缩”compressed_pair的大小以节约空间

32.base_from_member:将成员移动到辅助基类,使用模板技术来进行成员初始化,实

现子类初始化基类字段

33.vonversion:增强C++转型操作,提供多态对象转型的polymorphic_cast<>、

polymorphic_downcast<>和字面量转换的lexical_cast<>

34.flyweight:实现享元模式,享元对象是不可修改但可赋值的。

35.numeric conversion:提供用于安全数字转型的的一组工具,包括numeric_cast<>、

bounds<>和converter<>等

36.scope_exit:使用preprocessor库的预处理技术实现在退出作用域时的资源自动释

放,也可以执行任意的代码

37.statechart:一个功能完善且强大的优先状态自动机框架,完全支持UML语义,可

以从UML模型很方便的转换为C++代码。比起手工构建的状态机,可以极大的缩短

开发周期,并有足够的性能保证

38.units:实现物理学的量纲处理,包括长度、质量、时间、电流、温度、质量和发光

强度等。使用了模板元编程技术(MPL),支持国际标准量纲,也支持其他常用的非标准量纲。所有量纲运算都在编译时,无运行时开销

39.value_initialized:用于保证变量在声明时被正确的初始化,拥有零值或缺省值

40.utility:noncopyable、BOOST_BINARY、BOOST_CURRENT_FUNCTION等

1.checked_delete:编译期保证delete或delete[]操作删除的是一个完整类

定义,以避免运行时出现未定义行为

2.next()和prior():为迭代器提供后向和前向的通用处理方式

3.addressof:获得变量的真实地址,是取址符&的增强版本,对重载operator&

免疫

第15章Boost与设计模式

1.创建型模式

1.抽象工厂(Abstract Factory):抽象工厂模式就是把对象的创建封装在一

个类中,这个类的唯一任务就是按需生产各种对象,通过派生子类的方式抽

象工厂可以产生不同系列的、整套的对象。工厂类通常是单间,以保证在系

统的任何地方都可以访问,其中的每个方法都是工厂方法。在较小的软件系

统中,抽象工厂有时候会退化成一个没有子类的简单工厂

2.生成器(Builder):生成器模式分解了复杂对象的创建过程,创建过程可

以被子类改变,使同样的过程可以生产出不同的对象。生成器与抽象工厂不

同,它不是一次性的创建出产品,而是分步骤逐渐的装配出对象,因为可以

对创建过程进行更精细的控制

3.工厂方法(Factory Method):工厂方法把对象的创建封装在一个方法中,

子类可以改变工厂方法的生产行为生产不同的对象。工厂方法所属的类不一

定是一个工厂类。

4.原型(Prototype):使用类的实例通过拷贝的方式创建对象,具体的拷贝

行为可以定制。最常见的用法是实现一个clone成员函数,该函数创建一个

与原型形同或相似的新对象。因C++不能高效的返回一个对象,因此实践中

很少有完全实现的原型模式,可以通过提供拷贝构造函数和operator=部分

的实现原型模式

5.单件(Singleton):保证类有且仅有一个实例,并且提供一个全局的访问

点。通常的全局变量技术虽然也可以提供类似的功能,但不能防止用户创建

多个实例。单件的基本原理很简单,但有很多实现的变化

1.结构型模式

1.适配器(Adapter):把一个类的接口转换(适配)为另一个接口,从而在

不改变原有代码的基础上复用原代码。其别名wrapper更清晰的说明了它的

实现结构:包装原有对象,再给出一个新的接口

2.桥接(Bridge):分离了类的抽象和实现,使它们可以彼此独立的变化而互

不影响。适配器模式关心的是接口不匹配的问题,不关心接口的实现,只要

求对象能够协同工作;桥接模式的侧重点是接口的实现,通常接口是稳定的,

桥接解决实现的变化问题

3.组合(Composite):将小对象组合成树形结构,使用户操作组合对象如同

操作一个单个对象。组合模式定义了“部分-整体”的层次结构,基本对象

可以被组合成更大的对象,这些组合对象与基本对象拥有相同的接口。组合

是透明的,用法完全一致。

4.装饰(Decorator):可以在运行时动态的给对象增加功能。改变了对象的

能力范围,而且可以递归组合。通过生成子类的方式也可以为对象增加功能,

但它是静态的,而且大量的功能组合很容易产生“子类爆炸”现象。装饰模

式可以动态、透明的给对象增加职责,并且在不需要的时候很容易去除,使

用派生子类的方式无法达到这种灵活程度。

初学者 你应当如何学习C 以及编程

初学者,你应当如何学习C 以及编程 软件小兵 ruanjianxiaobing@sohu 作者:未知文章来源:天极Yesky软件频道 Javascript是世界上最受误解的语言,其实C 何尝不是。坊间流传的错误的C 学习方法一抓就是一大把。我自己在学习C 的过程中也走了许多弯路,浪费了不少时间。 为什么会存在这么多错误认识?原因主要有三个,一是C 语言的细节太多。二是一些著名的C 书籍总在(不管有意还是无意)暗示语言细节的重要性和有趣。三是现代C 库的开发哲学必须用到一些犄角旮旯的语言细节(但注意,是库设计,不是日常编程)。这些共同塑造了C 社群的整体心态和哲学。 单是第一条还未必能够成气候,其它语言的细节也不少(尽管比起C 起来还是小巫见大巫),就拿Javascript来说,作用域规则,名字查找,closure, for/in,这些都是细节,而且其中还有违反直觉的。但许多动态语言的程序员的理念我猜大约是学到哪用到哪罢。但C 就不一样了,学C 之人有一种类似于被暗示的潜在心态,就是一定要先把语言核心基本上吃透了才能下手写出漂亮的程序。这首先就错了。这个意识形成的原因在第二点,C 书籍。市面上的C 书籍不计其数,但有一个共同的缺点,就是讲语言细节的书太多——《C gotchas》,《Effective C 》,《More Effective C 》,但无可厚非的是,C 是这样一门语言:要拿它满足现代编程理念的需求,尤其是C 库开发的需求,还必须得关注语言细节,乃至于在C 中利用语言细节已经成了一门学问。比如C 模板在设计之初根本没有想到模板元编程这回事,更没想到C 模板系统是图灵完备的,这也就导致了《Modern C Design》和《C Template Metaprogramming》的惊世骇俗。 这些技术的出现为什么惊世骇俗,打个比方,就好比是一块大家都认为已经熟悉无比,再无秘密可言的土地上,突然某天有人挖到原来地下还蕴藏着最丰富的石油。在这之前的C 虽然也有一些细节,但也还算容易掌握,那可是C 程序员们的happy old times,因为C 的一切都一览无余,everything is figured out。然而《Modern C Design》的出世告诉人们,“瞧,还有多少细节你们没有掌握啊。”于是C 程序员们久违的激情被重燃起来,奋不顾身的踏入细节的沼泽中。尤其是,模板编程将C 的细节进一步挖掘到了极致——我们干嘛关心涉及类对象的隐式转换的优先级高低?看看boost::is_base_of就可以知道有多诡异了。 但最大的问题还在于,对于这些细节的关注还真有它合适的理由:我们要开发现代模板库,要开发active library,就必须动用模板编程技术,要动用模板编程技术,就必须利用语言的犄角旮旯,enable_if,type_traits,甚至连早就古井

运算符重载练习题.

运算符重载 一.单项选择题 1.下列运算符中,运算符在C++中不能重载。 A.?: B.+ C. D.<= 解:C++中不能被重载的运算符有:·,一,::,?:。本题答案为A。 2.下列运算符中,运算符在C++中不能重载。 A.&& B.[] C.:: D.new 解:c++中不能被重载的运算符有:·,·+,::,?:。本题答案为c。 3.下列关于运算符重载的描述中,是正确的。 A.运算符重载可以改变操作数的个数 B.运算符重载可以改变优先级 C.运算符重载可以改变结合性 D.运算符重载不可以改变语法结构 解:运算符重载不能改变操作数的个数、运算符的优先级、运算符的结合性和运算程的语法结构。本题答案为D。 4.友元运算符objl>obj2被C++编译器解释为。 A.operator>(objl,obj2) B.>(obj1,obj2) C.obj2.operator:>(obj1) D.objl.operator>(obj2) 解:重载为友元函数的运算符的调用形式如下: operator<运算符>(<参数1>,<参数2>) 等价于:<参数1><运算符><参数2> 本题答案为A。 5.现需要对list类对象使用的逻辑运算符“==”重载,以下函数声明是正确的。 A、list & list::operator==(const list &a); B、list list::operator==(const list &a); C、bool & list::operator==(const list &a); D、bool list::operator==(const list &a); 6. 以下类中分别说明了“+=”和“++”运算符重载函数的原型。如果主函数中有定义: fun m,c,d;,那么,执行语句c=m++; 时,编译器把m++解释为: (33) A) c.operator++(m); B) m=operator++(m); C) m.operator++(m); D) operator++(m); class fun { public: .. .. .. fun operator +=(fun ); friend fun operator ++(fun &,int); }; 答案:D 7. 在第33题中,当执行语句d+=m; 时,C++编译器对语句作如下解释: (34) A. d=operator+=(m); B. m=operator+=(d); C. d.operator+=(m); D. m.operator+=(d); 答案:C 8. 设有以下类定义,其中说明了“+”运算符重载函数的原型。这是一个友元函数,当类

疑问代词用法总结及练习

疑问代词用法总结及练习 句子是英语学习的核心。从句子使用的目的来分,它可分为四类 1、陈述句(肯定句和否定句) 2、疑问句(一般疑问句、特殊疑问句和选择疑问句) 3、祈使句(肯定句和否定句) 4、感叹句。 四大句子类型的相互转换,对于学生来讲是个难点,为此,可通过说顺口溜的形式来帮助学生解决这一难题。 如:将陈述句变成一般疑问句,可以变成这样的顺口留:疑问疑问调个头,把be(系动词“is are am”)放在最前头。 如:将陈述句的肯定句变成否定句,我们就可以这样说:否定,否定加“not”,加在何处,加在系动词的后面。 在句子相互转换的题型中,最难的要算“就下列划线部分提问”或是“看答句,写问句”这种题型了,其实,我们只要熟练掌握疑问词(what,what time, what colour, where, when, who, whose, which, how, how old ,how tall, how long, how big, how heavy , how much, how many等等)具体用法。

习题 一、选择正确的单词填空 (who, where, when) is that pretty girl She is my sister. are Jack and Tom They are behind you. do you go to school I go to school from Monday to Friday. has a beautiful flower John has a beautiful flower.

are they They are my parents. is my mother She is in the living room. are you going We are going to the bakery(面包坊). Jim and Wendy play ball They play ball in the afternoon. does he jog He jogs in the park. are you from I'm from Changchun city. 11. _______ is your birthday –On May 2nd. 12、_______ are you --- I`m in the office. 13. are you ---- I`m Alice. 二.用(what time, what color, what day, what)填空。 1. A: ______ _______ is it B: It is nine o’clock. 2. A: ______ _______ does your mother get up B: My mother gets up at 6:30. 3. A: ______ _______ do you go to bed B: I go to bed at 10:00. 4. A: ______ _______ do Diana and Fiona have supper B: Diana and Fiona have supper at 18:00. 5. A: ______ _______is it B: It is purple. 6. A: ______ _______ is the sky B: The sky is blue. 7. A: ______ _______ is your coat B: My coat is black. 8. A: ______ _______ is the dog B: The dog is white. 9. A: ______ _______ is today B: Today is Monday. 10. A: ______ _______ is tomorrow B: Tomorrow is Tuesday. 11. A: ______ _______ was yesterday B: Yesterday was Sunday. 12. A: ______ _______ do you like B: I like red. 13. A: ______ is this This is a computer. 14. A: ______ are you doing B: We are playing basketball.

数据库应用基础教程答案

数据库应用基础教程答案 【篇一:access数据库应用基础教程(第三版)习题及答 案】 txt>程(第三版)习题集答案 第1章数据库系统概述 1. 什么是数据库?什么是数据库系统?答:数据库(database) 是存放数据的仓库,严格的讲,数据库是长期存储在计算机内,有组 织的,可共享的大量数据集合。 数据库系统(database systems),是由数据库及其管理软件组成的系统。它是为适应数据处理的需要而发展起来的一种较为理想的 数据处理的核心机构。它是一个实际可运行的存储、维护和应用系 统提供数据的软件系统,是存储介质、处理对象和管理系统的集合体。 2. 什么是数据库管理系统?它有哪些主要功能? 答:数据库管理系统(database management system)是一种操纵 和管理数据 库的大型软件,用于建立、使用和维护数据库,简称dbms。它对数据库进行统一的管理和控制,以保证数据库的安全性和完整性。 数据库管理系统的主要功能有:数据定义、数据操作、数据库的运 行管理、数据组织、数据库的保护、数据库的维护和通信。 3. 说出几种常用的数据模型。 答:层次模型、网状模型、关系模型。 4. 什么是关系模型? 答:关系模型是用二维表的形式表示实体和实体间联系的数据模型。 5. 简述数据库设计的步骤。 答:需求分析、概念结构设计、逻辑结构设计、物理结构设计、数 据库的建立和测试、数据库运行和维护。 第2章 sql 语言简介 1. 什么是sql语言?sql语言具有哪些特点和功能? 答:sql是一种数据库查询和程序设计语言,用于存取数据以及查询更新和管理关系 数据库系统。 sql的特点和功能有:查询,操作,定义和控制四个方面,sql语言 具有高度的非过程化,语言简洁,语义明显,语法结构简单,直观

VS2010 C++下编译调试MongoDB源码

VS2010 C++下编译调试 MongoDB源码 考虑到m ongodb使用了boost库源码,参考m ongodb官方文档后,下载编译boost版本是1.42(时间为2010-2-2)或更新版本: boost版本1.42: https://www.doczj.com/doc/9b3856079.html,/projects/boost/files/boost/1.42.0/boost_1_42_0.zip/download 下载boost源码之后,我把boost解压在D盘。 1.在D:\boost_1_42_0\下找到该批处理文件bootstrap.bat,以vs2010命令行方式运行它,并最终生成bjam.exe可执行文件(详细结果及错误信息见生成的bjam.log日志)。 2.将生成的bjam.exe文件拷贝到“D:\boost_1_42_0”目录下,运行下面命令行: bjam stage variant=debug --stagedir="d:\boost_1_42_0" --with-files ystem --with-thread --with-date_time --with-program_options --layou t=versioned threading=multi toolset=msvc-10.0 如下 图:

注:i.如果要生成release链接库文件,需将上面的variant设置成release,形如:bjam stage variant=release ..... ii.如果要全部生成使用下面编译选项 bjam ...... --build-type=com plete 编译过程可能会用一些时间,最终会在"D:\boost_1_42_0" 生成一个lib目录,里面包括刚生成的库文件。 3.下载已用vs2010编译的SpiderMonkey库文件及源码包,并将其解压到D盘下,下载链接: https://https://www.doczj.com/doc/9b3856079.html,/dwight/vc2010_js 将该文件夹名称改为“js”(因为m ongodb项目会默认指定该路径寻找可用的lib及c源文件),

linux下编译C语言

GCC 支持了许多不同的语言,包括C、C++、Ada、Fortran、Objective C,Perl、Python 和Ruby,甚至还有Java。 Linux 内核和许多其他自由软件以及开放源码应用程序都是用 C 语言编写并使用GCC 编译的。 编译C++程序: -c 只编译不连接 g++ file1 -c -o file1.o g++ file2 -c -o file2.o g++ file1.o file.o -o exec g++ -c a.cpp 编译 g++ -o a a.o 生成可执行文件 也可以g++ -o a a.cpp直接生成可执行文件。 1. 编译单个源文件 为了进行测试,你可以创建“Hello World”程序: #include #include int main(int argc, char **argv) { printf(“Hello world!n”); exit(0); } 使用如下命令编译并测试这个代码: # gcc -o hello hello.c

# ./hello Hello wordl! 在默认情况下产生的可执行程序名为a.out,但你通常可以通过gcc 的“-o”选项来指定自己的可执行程序名称。 2. 编译多个源文件 源文件message.c包含一个简单的消息打印函数: #include void goodbye_world(void) { printf(“Goodbye, world!n”); } 使用gcc的“-c”标记来编译支持库代码: # gcc -c message.c 这一过程的输出结果是一个名为message.o的文件,它包含适合连接到一个较大程序的已编译目标代码。 创建一个简单的示例程序,它包含一个调用goodbye_world的main函数 #include void goodbye_world(void): int main(int argc, char **argv) { goodbye_world(); exit(0); }

英语一般疑问句用法总结

英语一般疑问句用法总结 1. 基本用法及结构 一般疑问句用于对某一情况提出疑问,通常可用yes和no来回答,读时用升调。其基本结构是“be / have / 助动词+主语+谓语(表语)”: Is he interested in going? 他有兴趣去吗? Have you ever been to Japan? 你到过日本吗? Does she often have colds? 她常常感冒吗? Did you ask her which to buy? 你问没问她该买哪一个? 2. 陈述句变一般疑问句的方法 (1) 动词be的否定式。动词be根据不同的时态和人称可以有am, is, are, was, were等不同形式,可用作连系动词(表示“是”、“在”等)和助动词(用于构成进行时态和被动语态等),但不管何种情况,构成疑问式时,一律将动词be的适当形式置于句首: Am I right? 我是对的吗? Are you feeling better today? 你今天感到好些了吗? Was he late for school? 他上学迟到了吗? (2) 动词have的疑问式。动词have根据不同的时态和人称可以有have, has, had等形式,可以用作实意动词和助动词,分以下情况讨论:

①用作实意动词表示状态,如表示拥有、患病或用于have to 表示“必须”等,在构成构成式时可以直接将have, has, had置于句首,也可根据情况在句首使用do, does, did: Does he have [Has he] anything to say? 他有什么话要说吗? Do you have [Have you] to leave so soon? 你必须这么早走吗? Did you have [Had you] any friends then? 他当时有朋友吗? ②用作实意动词表示动作,如表示“吃(=eat)”、“喝(=drin k)”、“拿(=take)”、“收到(=receive)”、“度过(=spend)”等,构成疑问式时不能将have提前至句首,而应在句首使用do, does, did: Does he have breakfast at home? 他在家吃早餐吗? Did you have a good time at the party? 你在晚会上玩得高兴吗? ③用作助动词构成完成时态,其疑问式总是将have等置于句首: Have you finished your work? 你的工作做完了吗? Has he left when you arrived? 你到达时他已离开了吗? (3) 情态动词的疑问式。情态动词的疑问式通常是将情态动词置于句首: Can you speak English? 你会说英语吗?

Linux 下编译C程序

Linux 下编译C程序 admin , 2010/03/05 12:55 , linux , 评论(0) , 阅读(76020) , Via 本站原创 GCC 支持了许多不同的语言,包括 C、C++、Ada、Fortran、Objective C,Perl、Python 和 Ruby,甚至还有Java。 Linux 内核和许多其他自由软件以及开放源码应用程序都是用 C 语言编写并使用 GCC 编译的。 编译C++程序: -c 只编译不连接 g++ file1 -c -o file1.o g++ file2 -c -o file2.o g++ file1.o file.o -o exec g++ -c a.cpp 编译 g++ -o a a.o 生成可执行文件 也可以 g++ -o a a.cpp直接生成可执行文件。 1. 编译单个源文件 为了进行测试,你可以创建“Hello World”程序: #include #include int main(int argc, char **argv) { printf(“Hello world! ”); exit(0); } 使用如下命令编译并测试这个代码: # gcc -o hello hello.c # ./hello Hello wordl! 在默认情况下产生的可执行程序名为a.out,但你通常可以通过 gcc 的“-o”

选项来指定自己的可执行程序名称。 2. 编译多个源文件 源文件message.c包含一个简单的消息打印函数: #include void goodbye_world(void) { printf(“Goodbye, world! ”); } 使用gcc的“-c”标记来编译支持库代码: # gcc -c message.c 这一过程的输出结果是一个名为message.o的文件,它包含适合连接到一个较大程序的已编译目标代码。 创建一个简单的示例程序,它包含一个调用goodbye_world的main函数 #include void goodbye_world(void): int main(int argc, char **argv) { goodbye_world(); exit(0); } 使用GCC编译这个程序: # gcc -c main.c 现在有了两个目标文件: message.o 和 main.o 。它们包含能够被 Linux 执行的目标代码。要从这个目标代码创建Linux可执行程序,需要再一次调用 GCC 来执行连接阶段的工作: # gcc -o goodbye message.o main.o 运行编译结果: # ./goodbye Goodbye, world! 前面这些单独的步骤也可以简化为一个命令,这是因为 GCC 对如何将多个源文件编译为一个可执行程序有内置的规则。 # gcc -o goodbye message.c main.c

一般疑问句、选择疑问句的详细用法备课讲稿

一般疑问句、选择疑问句的详细用法

一般疑问句、 (一)一般疑问句 1、一般疑问句概述 一般疑问句(general questions),也可称为“yes/no” questions(是否型问句),因为它一般是由yes或no回答的,如: —Can you swim to the other side?你能游到对岸吗? —Yes, I can.是的,我能。 —No,I can’t.不,我不能。 —Have you locked the door?你锁门了吗? —Yes,I have.是的,锁了。 —No,I haven’t. 不,没有锁。 2一般疑问句的结构 (1)基本的结构为:be/助动词/情态动词+主语+谓语/表语+(其他),句子要读升调,如: Are they your friends?他们是你的朋友吗? Does he go to school on foot?他是步行去上学吗? Will you be free tonight?你今晚有空吗? Can you play basketball?你会打篮球吗? (2)陈述句亦可用作一般疑问句,多用在非正式文体中,句末有问号,用升调,如: Somebody is with you?有人和你一起吗? He didn’t finish the work?他没有做完活吗? You are fresh from America,I suppose?我猜,你刚从美国回来吧? 3、一般疑问句的答语 (1)一般疑问句一般由yes或no来回答,如: —Are you tired?你累了吗? —Yes,I am.是的,累了。 —No, I’m not.不,不累。 —Does she do the cleaning?她扫除了吗?

易语言数据库教程之ACCESS数据库全操作

易语言数据库教程之ACCESS数据库 前面我们已经对比分析过易语言所支持的几种常见数据库,在这几种数据库中,我们先来学习一个ACCESS数据库,当然,MSSQL数据库是完全一样的。 数据库的学习可以说非常的简单,也可以说很不简单,这要看你的出发点来定,当然,前面所学习的易语言基础同样很重要! 和前面所有的教程一样,所讲的内容部分来源我的课堂教学,面对的是高中学生,有些地方的讲解会非常的详细,而有些地方又会相对简单的一笔带过,如果有什么地方你理解起来有困难的话,请与我联系,呵呵! 本教程并不是要把易语言中对ACCESS数据库的所有操作和应用都讲一遍,都讲清楚,那是不可能的,这一点倒是有点遗憾,但我会尽我所能把一些必需的内容讲清楚! 一、准备工作 1、ACCESS的安装参见Microsoft Office2003安装图解教程 2、ACCESS数据库中数据表的建立 3、易语言ACCESS数据库控件介绍 二、数据库操作 1、易语言ACCESS数据库的连接及打开 2、易语言ACCESS数据库的读操作 3、易语言ACCESS数据库的读操作问题解决 4、易语言ACCESS数据库的高级打开操作 5、易语言ACCESS数据库的写操作 6、易语言ACCESS数据库记录的简单修改 7、易语言ACCESS数据库记录的高级修改 三、数据库与高级表格

1、易语言ACCESS数据库与高级表格一 ACCESS数据库中数据表的建立 在ACCESS中建立一个数据库及在数据库中建立数据库其实是非常简单的。 1、新建数据库,这就不用多说了,在“文件”菜单下第一个就是“新建”,它的快捷键是“Ctrl+N”,和大多数软件完全一样。 2、新建的数据库第一步操作就是要保存,这也不用多说了,相信大家都会的。 3、新建数据表,新建的数据库如下图,是一个表都没有,新建一个数据表的方法有很多,这里我们选择“使用设计器创建表”,如下图所示。 3、这里我们以建立一个学生成绩表为例进行操作,随便写了一些字段在里面,注意一下字段的类型,有些是“自动编号”,有些是“文本”,有些是“数字”,根据需要来,最后别忘记给“id”这个字段设置为“主键”。

Windows版bjam的安装和配置

1、下载boost(或bjam)的源码,在命令行下执行如下命令: cd \tools\jam\src .\build.bat 其中指的是boost源码的根目录。这两条命令执行完毕,会产生一个bin.ntx86文件夹,里面含有一个编译生成的bjam.exe。将bjam.exe复制到C:\WINDOWS目录(或者PATH环境变量的其它取值)下。 2、在C:\Documents and Settings\All Users目录(或其它任意目录亦可)新建一个名为boost 的目录(取bjam或其它名字亦可,后面环境变量的值与此一致即可),将 \tools\build\v2目录及其前两级父目录复制到该boost目录里,则此时在C:\Documents and Settings\All Users\boost\tools\build\v2目录里可找到一个boost-build.jam文件,打开该文件并将boost-build的值改为: boost-build “C:/Documents and Settings/All Users/boost/tools/build/v2” ; 要注意此处的路径要用斜杠来隔开,但前面执行的命令涉及到的路径则用反斜杠隔开。另外,分号与前面的文字要有空格。 3、仍然在v2文件夹下,打开user-config.jam文件,找到以下一行: # using msvc ; 将“#”去掉。 4、添加BOOST_ROOT环境变量。具体操作为:右击“我的电脑”,选择“属性”->“高级”->“环境变量”,在“系统变量”方框下方点击“新建”,出现新建系统变量对话框。变量名填上BOOST_ROOT,变量值填上“C:\Documents and Settings\All Users\boost\tools\build\v2”(此路径即boost-build.jam所在的目录,注意要用英文环境下的双引号括起来)。至此,bjam 编译环境配置完成。 5、如果步骤4的环境变量不起作用,则用户的每个工程源码根目录必须存在一个步骤2修改好的boost-build.jam,bjam程序方可正常工作。但由于bjam会从工程根目录逐级搜索至工程所在磁盘分区根目录,若在每个磁盘分区根目录都复制一份boost-build.jam,则不管用户将工程源码放在什么地方,bjam程序都能正常读取boost-build.jam,然后编译工程了。 注意:在装bjam之前,必须保证系统中已安装了Visual Studio,否则无法编译出bjam.exe。如果想删除bjam,只需手动将C:\WINDOWS\bjam.exe、boost目录(用户创建的)和相关环境变量删除即可。 已发现及解决问题: 1、Visual Studio 2010的设置问题 如果系统安装的是Visual Studio 2010,则还需要向系统环境变量添加以下路径(假设VS安装在D盘): D:\Program Files\Microsoft Visual Studio 10.0\VC\bin 否则在编译bjam或者利用bjam编译用户工程时会报错,前者会提示找不到cl等命令,后者则会提示多个jam文件运行出错。

C++运算符重载例程详解

运算符重载就是对一个已有的运算符赋予新的含义,使之实现新功能。下面将通过简单的几个例程阐叙其用法。 例10.1 通过函数来实现复数相加。 #include using namespace std; class Complex //定义Complex类 {public: Complex( ){real=0;imag=0;} //定义构造函数 Complex(double r,double i){real=r;imag=i;} //构造函数重载Complex complex_add(Complex &c2); //声明复数相加函数void display( ); //声明输出函数private: double real; //实部 double imag; //虚部 }; Complex Complex::complex_add(Complex &c2) {Complex c; c.real=real+c2.real; c.imag=imag+c2.imag; return c;} void Complex::display( ) //定义输出函数{cout<<″(″<

int main( ) {Complex c1(3,4),c2(5,-10),c3; //定义3个复数对象c3=https://www.doczj.com/doc/9b3856079.html,plex_add(c2); //调用复数相加函数cout<<″c1=″; c1.display( ); //输出c1的值cout<<″c2=″; c2.display( ); //输出c2的值 cout<<″c1+c2=″; c3.display( ); //输出c3的值 return 0; } 例10.2 改写例10.1,重载运算符“+”,使之能用于两个复数相加。#include using namespace std; class Complex {public: Complex( ){real=0;imag=0;} Complex(double r,double i){real=r;imag=i;} Complex operator+(Complex &c2); //声明重载运算符的函数void display( ); private: double real; double imag; }; Complex Complex::operator+(Complex &c2) //定义重载运算符的函数

Boost编译和安装说明

Boost编译和安装说明 一、下载和安装 从官方主页https://www.doczj.com/doc/9b3856079.html,下载最新版,因为boost一部分类是需要编译成库才能使用的,所以需要准备好boost专用的编译辅助工具bjam。可直接使用boost安装包中附带的bjam源码来编译出bjam。 将boost安装包解压到E:\boost_1_53_0,运行E:\boost_1_53_0\bootstrap.bat批处理,会复制E:\boost_1_53_0\tools\build\v2\engine\ bin.ntx86\bjam.exe到目录E:\boost_1_53_0\下,注意最后bjam.exe必须与boost-build.jam在同级目录。 二、编译 打开命令提示符(cmd.exe)窗口并执行bjam,使用--help查看命令帮助。bjam的命令行参数涉及具体库的选择,会影响编译后的硬盘空间。 使用bjam命令如:bjam stage --toolset=msvc-10.0 --without-python --without-wave --without-test --stagedir="E:\boost_1_53_0_vc10" link=shared runtime-link=shared threading=multi debug release 下面详细解释一下每个参数的含义: 1)stage/install:stage表示只生成库(dll和lib),install还会生成包含头文件的 include目录。推荐使用stage,因为install生成的这个include目录实际就是boost 安装包解压缩后的boost目录(E:\boost_1_53_0\boost,只比include目录多几个非hpp的小文件),可以直接使用,而且不同的IDE都可以使用同一套头文件。 2)toolset:指定编译器,可选的如borland、gcc、msvc(VC6)、msvc-9.0(VS2008)、 msvc-10.0(VS2010)等。 3)without/with:选择不编译/编译哪些库,默认是全部编译。例如,without-python意 思是不需要编译python库。如果选择编译python的话,应该到python官方主页 https://www.doczj.com/doc/9b3856079.html,下载安装。 4)stagedir/prefix:stage时使用stagedir,install时使用prefix,表示编译生成文 件的路径。如果使用了install参数,那么还将生成头文件目录。推荐给不同的IDE 指定不同目录 5)build-dir:编译生成的中间文件的路径。默认就在根目录(E:\boost_1_53_0)下,目 录名为bin.v2,等编译完成后可具体查看一下是否生成了lib、dll文件。如果不需要可直接删除bin.v2目录 6)link:生成动态链接库/静态链接库。动态链接库使用shared方式,静态链接库使用 static方式。注意,static方式下生成的很多静态链接库大小都在几兆、几十兆。不推荐以static方式编译(without掉),巨型库黑名单:wave、graph、math、regex、test、program_options、serialization、signals。 7)runtime-link:动态/静态链接C/C++运行时库,有shared和static两种方式,与link 参数组合有4种方式。但通常一个工程用动态链接那么所有库都用动态链接,如果用静态链接那么所有库都用静态链接。所以只需要编译2种组合即可,即link=shared runtime-link=shared和link=static runtime-link=static。 8)threading:单/多线程编译。一般使用多线程程序,要指定multi方式;如果需要单线 程环境,使用single方式。

c++运算符重载习题

Task8-1 /* 1. 定义一个复数类Complex,重载运算符“+”,使之能用于复数的加法运算。将运算符函数重载为非成员、非友元的普通函数。编写程序,求两个复数之和*/ #include using namespace std; class Complex { public: Complex(){real=0;imag=0;} Complex(double r,double i){real=r;imag=i;} void display(); double real; double imag; }; void Complex::display() { cout<<"("<

文本预览
相关文档 最新文档