先把 PPT 放出来,文章以后有空再写吧。
![幻灯片2 幻灯片2](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%872_1.png)
![幻灯片3 幻灯片3](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%873_1.png)
![幻灯片4 幻灯片4](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%874_1.png)
![幻灯片5 幻灯片5](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%875_1.png)
![幻灯片6 幻灯片6](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%876_1.png)
![幻灯片7 幻灯片7](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%877_1.png)
![幻灯片8 幻灯片8](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%878_1.png)
![幻灯片9 幻灯片9](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%879_1.png)
![幻灯片10 幻灯片10](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%8710_1.png)
![幻灯片11 幻灯片11](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%8711_1.png)
![幻灯片12 幻灯片12](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%8712_1.png)
![幻灯片13 幻灯片13](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%8713_1.png)
![幻灯片14 幻灯片14](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%8714_1.png)
![幻灯片15 幻灯片15](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%8715_1.png)
![幻灯片16 幻灯片16](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%8716_1.png)
![幻灯片18 幻灯片18](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%8718_1.png)
![幻灯片19 幻灯片19](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%8719_1.png)
![幻灯片22 幻灯片22](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%8722_1.png)
![幻灯片23 幻灯片23](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%8723_1.png)
![幻灯片25 幻灯片25](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%8725_1.png)
![幻灯片27 幻灯片27](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%8727_1.png)
![幻灯片28 幻灯片28](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%8728_1.png)
![幻灯片29 幻灯片29](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%8729_1.png)
解释:integers 固定长度有什么好处?或者说为什么 <stdint.h> typedefs 没有解决问题?
1. 格式化输入输出 scanf/printf,int64_t 应该用什么格式?"%d" 还是 "%ld" 还是 "%lld" ? int_fast32_t 呢?
C99 为了解决这个,引入了 inttypes.h 头文件,其中定义了一堆宏,类似 PRId32, PRId64, PRIdFAST32,代码写起来是这样:
int64_t value = getValue();
printf("value = " PRId64 "\n", value);
2. 在 C++ 里,可以用函数重载 (overload) 来解决。但是 typedef 并不真正引入新类型(golang 与此不同),你如何知道 int_fast32_t 与 int64_t 是不是同一类型呢?另外还有 size_t/time_t 呢。比如
void foo(uint64_t x)
{}
void foo(size_t x)
{}
在有的系统(64 位 Linux)下会报编译错,因为 size_t 和 uint64_t 都是 unsigned long 类型,不能重载 foo 两次。怎么办?用宏和条件编译吗?
另外的例子是 time_t 和 int64_t:
void bar(time_t y)
{}
void bar(int64_t y)
{}
这段代码有错没错?取决于 time_t 与 int64_t 是不是同样的 typedef,如果整数不定长,除了用丑陋的 #if / #endif 条件编译,有办法解决吗?
![幻灯片30 幻灯片30](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%8730_1.png)
解释1:finally 有什么用?确实可以用栈上对象析构函数里的动作来模拟 finally,这又是一个 idiom,为什么不正大光明地让语言支持这一常用功能呢?
解释2:数据成员的默认值有什么用?
如果 class Foo 有一个 enum State state_; 成员,希望初始化为 INVALID_STATE。而 Foo 有 4 个构造函数,那么你得在每个构造函数里写:
Foo::Foo()
: state_(INVALID_STATE)
{}
Foo::Foo(XXXX1)
: state_(INVALID_STATE)
{}
Foo::Foo(XXXX1, YYYY2)
: state_(INVALID_STATE)
{}
Foo::Foo(XXXX1, YYYY2, ZZZZ3)
: state_(INVALID_STATE)
{}
state_ 的初始化要写四处。对于 enum,或许还可以用一个公用的 init() 来初始化。那么对于 class-type 如 string/vector,用 init() 这种办法就不能享受 initialization list 的好处了,因为对象在构造之后再被赋值,重复劳动。
更糟糕的是,万一你将来加了一个 int turnedOn_ 成员,初始值为 -1,你得在 4 个构造函数那里去增加初始化代码,万一漏了一处,等待你的就是 uninitialized value,自求多福吧。
关于 allocator,它没有带来任何好处,如果内存分配这种事情都需要重新定义,重写数据结构也是理所应当的:
http://blog.csdn.net/Solstice/archive/2009/08/02/4401382.aspx
auto_ptr 为什么是坏的,因为太容易用错,且不能放到标准容器里。
Gregory Colvin 最早设计的 auto_ptr 是没有“所有权转移”这个语意的,跟现在的 scoped_ptr 一样。但是标准委员会莫名其妙地加了这个语意,造成了很多陷阱。
scoped_ptr/unique_ptr/shared_ptr 都是更好的替代,语意明确,不容易用错。
至于为什么 valarray 是坏的,见《C++ 标准程序库》相关章节,再说,有谁会用 valarray 做科学计算吗?同样坏的还有 vector<bool>。
如果 XML/logging 这些基本构件不标准化,很难让几个第三方库协作起来,因为每个库都会自己发明一套互不兼容的 logging 和 XML 处理机制。
如果程序里要把 library A 生成的 XML 对象传到 library B 里,恐怕只好用字符串来作为中间媒介,这会增加很多无谓序列化/反序列化的开销。
logging 也是如此,如果没有标准化接口,如何让 library A 和 library B 按相同的格式写到同一个日志文件呢?恐怕又得自己写写 adapter 来协调这些第三方库了。
![幻灯片32 幻灯片32](http://www.cppblog.com/images/cppblog_com/Solstice/WindowsLiveWriter/C_11C4B/%E5%B9%BB%E7%81%AF%E7%89%8732_1.png)