{{sellerTotalView > 1 ? __("sellers", {number: sellerTotalView}) : __("seller", {number: sellerTotalView}) }}, {{numTotalView > 1 ? __("items", {number: numTotalView}) : __("item", {number: numTotalView}) }}
free FREE

Change Your Zip Code

Inventory information and delivery speeds may vary for different locations.

Location History

{{email ? __('Got it!') : __('Restock Alert')}}

We will notify you by email when the item back in stock.

Cancel
Yami

Jingdong book

Imperfect C++(中文版)

{{buttonTypePin == 3 ? __("Scan to view more PinGo") : __("Scan to start")}}

Imperfect C++(中文版)

{{__(":people-members", {'people': item.limit_people_count})}} {{ itemCurrency }}{{ item.valid_price }} {{ itemCurrency }}{{ item.invalid_price }} {{ itemDiscount }}
Ends in
{{ itemCurrency }}{{ item.valid_price }}
{{ itemCurrency }}{{ priceFormat(item.valid_price / item.bundle_specification) }}/{{ item.unit }}
{{ itemDiscount }}
{{ itemCurrency }}{{ item.valid_price }} {{ itemCurrency }}{{ priceFormat(item.valid_price / item.bundle_specification) }}/{{ item.unit }} {{ itemCurrency }}{{ item.invalid_price }} {{itemDiscount}}
{{ itemCurrency }}{{ item.valid_price }}
Sale ends in
Sale will starts after Sale ends in
{{ getSeckillDesc(item.seckill_data) }}
{{ __( "Pay with Gift Card to get sale price: :itemCurrency:price", { 'itemCurrency' : itemCurrency, 'price' : (item.giftcard_price ? priceFormat(item.giftcard_price) : '0.00') } ) }} ({{ itemCurrency }}{{ priceFormat(item.giftcard_price / item.bundle_specification) }}/{{ item.unit }}) Details
Best before

Currently unavailable.

We don't know when or if this item will be back in stock.

Unavailable in your area.
Sold Out

Details

Full product details
Editer Recommend

《Imperfect C++》(中文版)是市面上唯一一本讨论C++的不足之处,并给出解决方案的C++经典图书。由知名译者荣耀与刘未鹏合译,在技术开发者中拥有极大影响力。
Content Description

荣耀与刘未鹏合译的重量级编程图书,市面上唯一一本讨论C++不足之处,并给出解决方案的图书。
即便是C++阵营里最忠实的信徒,也不得不承认:C++语言并不完美。实际上,世界上也没有完美的编程语言。
如何克服C++类型系统的不足?在C++中,如何利用约束、契约和断言来实施软件设计?如何处理被C++标准所忽略的动态库、静态对象以及线程等有关的问题?隐式转换有何替代方案?本书将为你一一解答这些问题。针对C++的每一个不完美之处,本书都具体地分析原因,并探讨实用的解决方案。书中也不乏许多作者创新的、你从未听说过或使用的技术,但这些确实能帮助你成为C++方面的专家。
《Imperfect C++》(中文版)适合有一定经验的C++程序员和项目经理阅读,也适合对C++编程的一些专门或高级话题感兴趣的读者参考。
Author Description

Matthew Wilson,是一名软件开发顾问,也是STLSoft库的创建者。他为双月刊C/C++ Users Journal撰写关于将C/C++与其他语言和技术进行整合的专栏文章,同时也是C++ Experts Forum在线专栏作家。Wilson有十余年C++开发经验。
荣耀,南京师范大学教师。他是一名C++讲师和研究者,译有《C++必知必会》、《C++ Templates全览》以及《C++ Template Metaprogramming中文版》(中文繁体版)等,并在期刊杂志上发表过多篇文章。他原任电力自动化研究院工程师与项目经理,是数个企业级信息系统项目负责人。
刘未鹏,南京大学计算机系硕士毕业,现就职于微软亚洲研究院创新工程中心。
Comments

“千万不要被书名所误导!这是一本拥抱(而非诋毁)C++的著作。它有着独特的定位:为现实世界中的程序员提供切合实际的解决方案,以解决C++语言自身的各种“不完美”。
世界上没有完美的编程语言。在本书中,Matthew Wilson不但为我们指出C++中诸多不完美之处,还提供了经过实践检验的应对技术和技巧,便于我们利用“不完美的C++”编写出近乎完美的代码——强健、高效、灵活、可移植、优雅的代码,而这些代码在声称为“完美的语言”中往往更难实现。
本书对给出的每一个“不完美”都进行了细致的探讨:为什么说它是一个“不完美”?对其修复的指导思想是什么?有时候只是告诫你避免做些什么,给出一些约束和建议,更多的时候则为你提供现实的解决方案,这些方案往往离不开对现代模板编程技术的使用。
书中包含有许多你未曾听过或用过的技术,有些属于作者的创新,有些则是对现有技术的精化,二者均被提升到“范式”的高度。例如:应用程序二进制接口(ABI)、垫片(Shim)、饰面(Veneer)、螺栓(Bolt-in)、区间(range)、属性(property)等。不少主题难度大,此前为其他C++专家所忽略。要探讨它们除了需要勇气外,第一手经验更是不可或缺。作为STLSoft库的主创者,Matthew在举例时,对Windows API、MFC、ATL、COM以及UNIX等都是信手拈来。
除了丰富的实践、扎实的理论以及缜密的逻辑外,Matthew的文笔流畅,语言幽默,说理直接,字里行间流露出过人的自信,使得本书极具阅读趣味。
本书具有一定的阅读门槛,目标读者为中、高级职业C++程序员。书中展示的代码示例、编程技术往往在几款甚至十几款编译器上进行验证, 辅以表格对其各色特性加以比较,并针对不同编译器所表现出的差异性而给出高效、可移植的解决方案——就像很多现实世界中的C++程序员应该做(而没做到)的那样。如果你正在寻找一本真材实料的“C++实战”参考书,本书不会让你失望。
本书中文版由我和刘未鹏先生合译。未鹏思维敏捷,技术、文笔俱佳,我很高兴与他合作。
感谢陈冀康编辑给予的理解和支持。感谢朱艳的照料和热爱。荣珅则常常用他的小拳头乱砸书房的门,并大声地叫“爸爸”,这种干扰让我获得了必不可少的休息时间。
已有的经典名著使得C++新书问世难度加大,后来者若无过人之处就很难引起C++社群的注意,Imperfect C++、C++ Common Knowledge以及C++ Template Metaprogramming等佳作一经问世便得到广泛的关注。作为译者(之一),我祝愿它们能够带给各位久违的快乐!
——荣耀

刀有很多种,有单刀,双刀,朴刀,戒刀,锯齿刀,砍山刀,鬼头刀,雁翎刀,五凤朝阳刀,鱼鳞紫金刀。
—— 古龙《飞刀,又见飞刀》

这里我们要说的刀,是瑞士军刀,瑞士军刀其实严格来说并不能算是一种刀,其功能的繁杂和精细已然超过了刀的范畴。它包含的工具一般有主刀、小刀、剪刀、开瓶器、木锯、小改锥、拔木塞钻、牙签、小镊子等,而在一些工具上还设计了多种功用,如开瓶器上,就具有开瓶、平口改锥、电线剥皮槽3种功用。随着时代的发展,一些新兴的电子技术也被引入瑞士军刀中,如内藏激光笔、电筒等。
瑞士军刀是军人在野外生存的必备工具,其小体积浓缩众多实用功能的精心设计能够将一把刀的容限发挥到最大,丝毫不逊于《第一滴血》中蓝博带在身上的那把锐利的寒光闪闪的钢刀。
那么现在你拿在手里的这本书就是一把瑞士军刀!
这是一本非常特别的C++图书,在市面上已经存在的大量经典C++书籍当中,这本书的着眼点和写作风格使它显得那么特立独行和标新立异,甚至有点另类。书中几乎巨细靡遗地涵盖了C++中大大小小的不完美之处,并以一系列成功案例证明C++的确不完美同时也提供了迂回之道、解决之道,再加上其用本主义的立场,正如同一把实用的瑞士军刀,功能繁杂而面面俱到,实用之至。同其他C++著作不一样,本书虽然尊重标准,但同时又超越标准,当标准不能满足需求或成为拦路石的时候,需求才是第一位的,于是有了作者所谓的“不完美主义的实践者”以及“不完美工具箱”之说。此外,作者的所谓“苦行僧式编程”哲学在我看来也是极其实用的一种编码方式!
我们以前看到的绝大部分C++书籍可说是统统走的“阳关大道”,然而Matthew这本书却偏要走他的“独木小桥”,蹊径虽小,然则别有一番风味和景观。我们意识到原来C++中也存在着如此多大大小小的不完美之处,就像宫崎俊电影中的那些打满补丁的海盗飞机一样。Bjarne本就说过,C++是为“用本”而设计的,诚然!而本书最大的趣味就在于它并不去一味抱怨这些缺点,而是积极地采取其他替代方案来达到同样的目的,并借此展现出C++自由强大的一面!
作者Matthew常用“survive”一词来描述在编码的现实世界中的境况,作为STLSoft库的主要编写者,他十几年来积累的经验在书中充盈四溢,很多我们平常看不到的方面都会被他挑出来,甚至连我这个译者都觉得有点“啰嗦”。不过,对于喜欢他这种“唠叨”讲法的人,他那种辨证的严密论证法倒是能令你获益颇多。另外,书中随处可见具有作者个人特色的幽默,在大量平淡无奇的技术书籍当中可算是一个亮点。
本书的一个小缺憾就是它不适合初学者,某些地方甚至对于中级读者来说都有一定的难度,作者自己经验非常丰富,因此有些地方就不加解释地一带而过,为此译者适当添加了一些译注,以便读者理解和阅读。
最后,感谢荣耀先生在本书初译的过程中一直给予的支持和信任,并容忍我总是延期交付各章译稿。荣耀先生对技术的精益求精和一丝不苟也令我在翻译的过程中获益良多。
最大的感激要归于我的父母和我的爷爷,感谢他们一直以来对我的追求的支持和鼓励,没有他们我无法想象能够完成这项工作。
希望这本令我在翻译过程中获益匪浅的书也能够给你带来美妙而独一无二的阅读享受,Let’s dig in!
——刘未鹏
Catalogue

第一部分 基础知识
第1章 强制设计:约束、契约和断言
1.1 绿蛋和火腿
1.2 编译期契约:约束
1.2.1 must_have_base()
1.2.2 must_be_subscriptable()
1.2.3 must_be_subscriptable_
as_decayable_pointer()
1.2.4 must_be_pod()
1.2.5 must_be_same_size()
1.2.6 使用约束
1.2.7 约束和TMP
1.2.8 约束:尾声
1.3 运行期契约:前置条件、后置条件和不变式
1.3.1 前置条件
1.3.2 后置条件
1.3.3 类不变式
1.3.4 检查?总是进行
1.3.5 DbC还是不DbC
1.3.6 运行期契约:尾声
1.4 断言
1.4.1 获取消息
1.4.2 不恰当的断言
1.4.3 语法以及64位指针
1.4.4 避免使用verify()
1.4.5 为你的断言命名
1.4.6 避免使用#ifdef_DEBUG
1.4.7 DebugBreak()和int 3
1.4.8 静态/编译期断言
1.4.9 断言:尾声
第2章 对象生命期
2.1 对象生命周期
2.2 控制你的客户端
2.2.1 成员类型
2.2.2 缺省构造函数
2.2.3 拷贝构造函数
2.2.4 拷贝赋值
2.2.5 new和delete
2.2.6 虚析构
2.2.7 explicit
2.2.8 析构函数
2.2.9 友元
2.3 MIL及其优点
2.3.1 取得一块更大的场地
2.3.2 成员顺序依赖
2.3.3 offsetof()
2.3.4 MIL:尾声
第3章 资源封装
3.1 资源封装分类
3.2 POD类型
3.2.1 直接操纵
3.2.2 API函数和透明类型
3.2.3 API函数和不透明类型
3.3 外覆代理类
3.4 RRID类型
3.4.1 缺省初始化:缓式初始化
3.4.2 未初始化
3.5 RAII类型
3.5.1 常性RAII和易变性
RAII
3.5.2 内部初始化和外部初
始化
3.5.3 RAII排列
3.6 RAII:尾声
3.6.1 不变式
3.6.2 错误处理
第4章 数据封装和值类型
4.1 数据封装的分类学
4.2 值类型和实体类型
4.3 值类型的分类学
4.4 开放式类型
4.4.1 POD开放式类型
4.4.2 C++数据结构
4.5 封装式类型
4.6 值类型
4.7 算术值类型
4.8 值类型:尾声
4.9 封装:尾声
第5章 对象访问模型
5.1 确定性生命期
5.2 返回拷贝
5.3 直接交给调用者
5.4 共享对象
第6章 域守卫类
6.1 值
6.2 状态
6.3 API和服务
6.3.1 API
6.3.2 服务
6.4 语言特性

第二部分 生存在现实世界
第7章 ABI
7.1 共享代码
7.2 C ABI需求
7.2.1 结构布局
7.2.2 调用约定、符号名以及目标文件格式
7.2.3 静态连接
7.2.4 动态连接
7.3 C++ ABI需求
7.3.1 对象布局
7.3.2 虚函数
7.3.3 调用约定和名字重整
7.3.4 静态连接
7.3.5 动态连接
7.4 现在知道怎么做了
7.4.1 extern“C”
7.4.2 名字空间
7.4.3 extern“C++”
7.4.4 获得C++类的句柄
7.4.5 “由实现定义”的隐患
第8章 跨边界的对象
8.1 近乎可移植的虚函数表
8.1.1 虚函数表布局
8.1.2 动态操纵虚函数表
8.2 可移植的虚函数表
8.2.1 利用宏进行简化
8.2.2 兼容的编译器
8.2.3 可移植的服务端对象
8.2.4 简化可移植接口的实现
8.2.5 C客户代码
8.2.6 OAB的约束
8.3 ABI/OAB尾声
第9章 动态库
9.1 显式调用函数
9.1.1 显式调用C++函数
9.1.2 打破C++访问控制
9.2 同一性:连接单元和连接空间
9.2.1 连接单元
9.2.2 连接空间
9.2.3 多重身份
9.3 生命期
9.4 版本协调
9.4.1 丢失的函数
9.4.2 变化的签名
9.4.3 行为的改变
9.4.4 常量
9.5 资源所有权
9.5.1 共享池
9.5.2 返还给被调用方
9.6 动态库:尾声
第10章 线程
10.1 对整型值的同步访问
10.1.1 操作系统函数
10.1.2 原子类型
10.2 对(代码)块的同步访问:临界区
10.2.1 进程间互斥体和进程内互斥体
10.2.2 自旋互斥体
10.3 原子整型的性能
10.3.1 基于互斥体的原子整型
10.3.2 运行期按架构派发
10.3.3 性能比较
10.3.4 原子整型操作:尾声
10.4 多线程扩展
10.4.1 synchronized
10.4.2 匿名synchronized
10.4.3 atomic
10.5 线程相关的存储
10.5.1 重入
10.5.2 线程相关的数据/线程局部存储
10.5.3 declspec(thread)和
TLS
10.5.4 Tss库
10.5.5 TSS的性能
第11章 静态对象
11.1 非局部静态对象:全局对象
11.1.1 编译单元内的顺序性
11.1.2 编译单元间的顺序性
11.1.3 利用main()避免全局
变量
11.1.4 全局对象尾声:顺序性
11.2 单件
11.2.1 Meyers单件
11.2.2 Alexandrescu单件
11.2.3 即时Schwarz计数器:
一个极妙的主意
11.2.4 对API计数
11.2.5 被计数的API、外覆类、
代理类:最终得到一个顺序化的单件
11.3 函数范围内的静态对象
11.3.1 牺牲缓式求值能力
11.3.2 自旋互斥体是救星
11.4 静态成员
11.4.1 解决连接问题
11.4.2 自适应代码
11.5 静态对象:尾声
第12章 优化
12.1 内联函数
12.1.1 警惕过早优化
12.1.2 只含有头文件的库
12.2 返回值优化
12.3 空基类优化
12.4 空派生类优化
12.5 阻止优化

第三部分 语言相关的议题
第13章 基本类型
13.1 可以给我来一个字节吗
13.1.1 标明符号
13.1.2 一切都在名字之中
13.1.3 窥探void内部
13.1.4 额外的安全性
13.2 固定大小的整型
13.2.1 平台无关性
13.2.2 类型相关的行为
13.2.3 固定大小的整型:尾声
13.3 大整型
13.4 危险的类型
13.4.1 引用和临时对象
13.4.2 bool
第14章 数组和指针
14.1 不要重复你自己
14.2 数组退化为指针
14.2.1 下标索引操作符的交换性
14.2.2 阻止退化
14.3 dimensionof()
14.4 无法将数组传递给函数
14.5 数组总是按地址进行传递
14.6 派生类的数组
14.6.1 通过指针保存多态类型
14.6.2 提供非缺省的构造函数
14.6.3 隐藏向量式new和
delete
14.6.4 使用std::vector
14.6.5 确保类型的大小相同
14.7 不能拥有多维数组
第15章 值
15.1 NULL的是非曲直
15.2 回到0
15.3 屈服于事实
15.4 字面量
15.4.1 整型
15.4.2 后缀
15.4.3 字符串
15.5 常量
15.5.1 简单常量
15.5.2 类类型常量
15.5.3 成员常量
15.5.4 类类型的成员常量
第16章 关键字
16.1 interface
16.2 temporary
16.3 owner
16.4 explicit(_cast)
16.4.1 使用显式访问函数
16.4.2 模拟显式转换
16.4.3 使用特性垫片
16.5 unique
16.6 final
16.7 不被支持的关键字
第17章 语法
17.1 类的代码布局
17.2 条件表达式
17.2.1 “使它布尔”
17.2.2 一个危险的赋值
17.3 for
17.3.1 初始化作用域
17.3.2 异质初始化类型
17.4 变量命名
17.4.1 匈牙利命名法
17.4.2 成员变量
第18章 Typedef
18.1 指针typedef
18.2 定义里面有什么
18.2.1 概念性的类型定义
18.2.2 上下文相关的类型定义
18.3 别名
18.3.1 错误的概念性类型互换
18.3.2 不能对概念性类型进行重载
18.4 true_typedef
18.5 好的、坏的、丑陋的
18.5.1 好的typedef
18.5.2 坏的typedef
18.5.3 可疑的typedef

第四部分 感知式转换
第19章 强制
19.1 隐式转换
19.2 C++中的强制
19.3 适合使用C强制的场合
19.4 模仿强制
19.5 explicit_cast
19.6 literal_cast
19.7 union_cast
19.8 comstl::interface_cast
19.8.1 interface_cast_addref
19.8.2 interface_cast_noaddref
19.8.3 interface_cast_test
19.8.4 接口强制操作符的实现
19.8.5 保护引用计数
19.8.6 interface_cast_base
19.8.7 IID_traits
19.8.8 interface_cast 尾声
19.9 boost::polymorphic_cast
19.10 强制:尾声
第20章 垫片
20.1 拥抱变化 拥抱自由
20.2 特性垫片
20.3 逻辑垫片
20.4 控制垫片
20.5 转换垫片
20.6 复合式垫片概念
20.6.1 访问垫片
20.6.2 返回值生命期
20.6.3 泛化的类型操纵
20.6.4 效率方面的考虑
20.7 名字空间和Koenig查找
20.8 为何不使用traits
20.9 结构一致性
20.10 打破巨石
20.11 垫片:尾声
第21章 饰面
21.1 轻量级RAII
21.2 将数据和操作绑定在一起
21.2.1 pod_veneer
21.2.2 创建日志消息
21.2.3 减少浪费
21.2.4 类型安全的消息类
21.3 “擦亮”饰面概念
21.4 饰面:尾声
第22章 螺栓
22.1 添加功能
22.2 皮肤选择
22.3 非虚重写
22.4 巧用作用域
22.5 拟编译期多态:逆反式螺栓
22.6 参数化多态包装
22.7 螺栓:尾声
第23章 模板构造函数
23.1 不易察觉的开销
23.2 悬挂引用
23.3 模板构造函数特化
23.4 实参代理
23.5 明确实参的范畴
23.6 模板构造函数:尾声

第五部分 操作符
第24章 operator bool()
24.1 operator int() const
24.2 operator void *() const
24.3 operator bool() const
24.4 operator !() const
24.5 operator boolean const *()const
24.6 operator int boolean::*()const
24.7 在现实世界中操作
24.8 operator!
第25章 快速、非侵入性的字符串拼接
25.1 fast_string_concatenator<>
25.1.1 与用户自定义的字符
串类协同工作
25.1.2 将“拼接子”串起来
25.1.3 fast_string_concatenator

25.1.4 内部实现
25.2 性能
25.3 与其他字符串类协作
25.3.1 整合进标准库中
25.3.2 整合进可改动的现存类中
25.3.3 与不可更改的类互操作
25.4 拼接提示
25.5 病态括号
25.6 标准化
第26章 你的地址是什么
26.1 无法得到真实的地址
26.1.1 STL式元素存放
26.1.2 ATL外覆类和CAdapt
26.1.3 获取真实的地址
26.2 在转换过程中发生了什么
26.3 我们返回什么
26.4 你的地址是什么:尾声
第27章 下标索引操作符
27.1 指针转换与下标索引操作符
27.1.1 选择隐式转换操作符
27.1.2 选择下标索引操作符
27.2 错误处理
27.3 返回值
第28章 增量操作符
28.1 缺少后置式操作符
28.2 效率
第29章 算术类型
29.1 类定义
29.2 缺省构造
29.3 初始化(值构造)
29.4 拷贝构造函数
29.5 赋值
29.6 算术操作符
29.7 比较操作符
29.8 访问值
29.9 sinteger64
29.10 截断、提升以及布尔测试
29.10.1 截断
29.10.2 提升
29.10.3 布尔测试
29.11 算术类型:尾声
第30章 短路

第六部分 扩展C++
第31章 返回值生命期
31.1 返回值生命期问题分类
31.1.1 局部变量
31.1.2 局部静态对象
31.1.3 析构后指针
(Postdestruction Pointers)
31.2 为何按引用返回
31.3 解决方案1:integer_to_string<>
31.4 解决方案2--TSS
31.4.1 --declspec(thread)
31.4.2 Win32 TLS
31.4.3 平台无关的API
31.4.4 RVL
31.5 解决方案3--扩展RVL
31.5.1 解决线程内的RVL-LS问题
31.5.2 RVL
31.6 解决方案4--静态数组大
小决议
31.7 解决方案5--转换垫片
31.8 性能
31.9 RVL:垃圾收集的大胜利
31.10 可能的应用
31.11 返回值生命期:尾声
第32章 内存
32.1 内存分类
32.1.1 栈和静态内存
32.1.2 栈扩张
32.1.3 堆内存
32.2 两者之间的折衷
32.2.1 alloca()
32.2.2 VLA
32.2.3 auto_buffer<>
32.2.4 使用auto_buffer
32.2.5 EBO,在哪里
32.2.6 性能
32.2.7 堆、栈以及其他
32.2.8 pod_vector<>
32.3 配置器
32.3.1 函数指针
32.3.2 配置器接口
32.3.3 每库初始化(Per-library
Initialization)
32.3.4 每调用指定(Per-Call
Specification)
32.4 内存:尾声
第33章 多维数组
33.1 激活下标索引操作符
33.2 运行时确定大小
33.2.1 可变长数组
33.2.2 vector< ... vector... >
33.2.3 boost::multi_array
33.2.4 fixed_array_1/2/3/4d
33.3 编译期确定大小
33.3.1 boost::array
33.3.2 static_array_1/2/3/4d
33.4 块访问
33.4.1 使用std::fill_n()
33.4.2 array_size垫片
33.5 性能
33.5.1 运行期确定大小
33.5.2 编译期确定大小
33.6 多维数组:尾声
第34章 仿函数和区间
34.1 语法混乱
34.2 for_all()
34.2.1 数组
34.2.2 命名
34.3 局部仿函数
34.3.1 手写循环
34.3.2 自定义仿函数
34.3.3 内嵌的仿函数
34.3.4 温和一些
34.3.5 泛化的仿函数:类型隧
道(Type Tunneling)
34.3.6 再进一步,走得太
远了
34.3.7 局部仿函数和回调
API
34.4 区间
34.4.1 区间概念
34.4.2 概念性区间
34.4.3 可迭代区间
34.4.4 区间算法和标签
34.4.5 过滤器
34.4.6 虚伪
34.5 仿函数和区间:尾声
第35章 属性
35.1 编译器扩展
35.2 可供选择的实现方案
35.2.1 将属性的实现分门
别类
35.2.2 EMO
35.3 字段属性
35.3.1 field_property_get
35.3.2 field_property_set
35.3.3 内置式字段属性:
尾声
35.3.4 field_property_get_
external
35.3.5 field_property_set_
external
35.3.6 Hack掉
35.4 方法属性
35.4.1 method_property_get
35.4.2 method_property_set
35.4.3 method_property_getset
35.4.4 谨防无限循环
35.4.5 method_property_get
_external
35.4.6 method_property_set
_external
35.4.7 method_property_getset
_external
35.5 静态属性
35.5.1 静态字段属性
35.5.2 内置式静态方法属性
35.5.3 外置式静态方法属性
35.6 虚属性
35.7 属性的使用
35.7.1 泛化性
35.7.2 错误诊断中的类型
替换
35.8 属性:尾声
附录A 编译器和库
A.1 编译器
A.2 库
A.2.1 Boost
A.2.2 STLSoft
A.2.3 其他库
A.3 其他资源
A.3.1 期刊
A.3.2 其他语言
A.3.3 新闻组
附录B “谦虚点,别骄傲”
B.1 操作符重载
B.2 后悔DRY
B.3 偏执式编程
B.4 精神错乱
附录C Arturius
附录D 随书光盘
尾声
参考书目
Introduction

或许我不像喜欢我的孩子们那样喜爱C++,甚至或许我对C++的喜爱都比不上我对骑自行车在坡度为32°、光滑度为10%的柏油路上爬坡的热衷, 尽管有时这些喜爱之情的确十分接近。我庆幸我有这样的人生,让我得以将生命中的部分时间用来实践或阐释Frederick P.Brooks的名言:“尽量发挥想象力进行创造”。我更要感激的是我能够跟这门如此强大、危险却又诱人的语言相伴。

这些话听起来似乎蛮华丽动听,但你可能是因为看到本书的书名才买下它的,以为本书是一本抨击C++的图书。你可能是Java或C或其他主流语言的热衷者,因而买这本书可能是想从中找到支持你远离C++的理由。倘若果真如此,你会失望的,因为本书并不是举办一切C++批判大会。不过先别急着离开,因为你或许能够从中找到令你开始接触C++的理由。

你将从中学到什么

我写这本书的目的在于给予开发同行们一些能量。它以虽批评但具建设性的眼光来看待C++及其不完美之处,并给出实际的措施以避免或改善这种不完美。我希望你在读完本书后能够对下面这些问题有一个更好的把握:

如何克服C++类型系统中的某些不足。

模编程在提高代码灵活性和健壮性上的强大能力。

如何在(当前标准尚不予置理的)未定义行为的险恶丛林中生存下来。后者包括动态库、静态对象以及线程等。

隐式转换的代价、它所带来的问题,及其替代方案,即基于显式转换的、高效且易于控制的泛用性编程。

如何编写能够与(或更容易令它们与)其他编译器、库、线程模型等兼容的软件。

编译器“在幕后”都做了些什么?你对编译器可以施加什么样的影响。

数组和指针之间微妙而棘手的互操作性,以及用于防止它们的行为变得彼此相似的技术。

C++对RAII(Resource Acquisition Is Initialization,资源获取即初始化)机制的支持,以及该机制可以被运用到的各种问题领域。

如何通过最大限度地榨取编译器的侦错能力来节省你自己所需花费的工夫。

有了上面这些“装备”,你编写的代码将更有效率、更具可维护性、更健壮,也更具灵活性。

我的意图是,即便是经验丰富的C++实践者也能从本书中发现新思想和新技术,从而引发他们的灵感并提高其现有的实战能力。经验较少的程序员则能领会其中包含的有关原则并将相关技术应用到自己的工作中,在增长见识的同时弥补自己对一些技术细节理解上的疏漏。

我并不指望你们所有人都完全同意我所说的一切,但我期望哪怕是最有争议的内容也能激发你去真正弄明白自己对这门强大语言的使用问题。

我假设你们已经知道

除非有人想写一本很厚的书,否则他必须假设许多知识是读者已经知道的。当然,规定大家必须首先读完某些书籍的做法过于粗鲁,但我假设你们的知识和经验能使你们轻松地理解Scott Meyer的Effective C++系列和Herb Sutter的Exceptional C++系列中讲述的绝大部分概念。我还假设你们拥有一本C++“圣经”,即Bjarne Stroustrup的The C++ Programming Language。我并不指望你们仔细阅读该书的每一页(我都还没有做到这一点),但你们应当将这本书作为这门语言的终极参考,因为它的确是字字珠玑。

本书中包含有相当多的模板代码(哪一本现代C++书籍不是如此呢),但我并没有假设你是名大师级的人物, 或掌握了高阶元编程知识。话虽如此,我还是建议你们最好熟悉如何使用模板,比如组成C++标准库中最流行的部分的那些内容。我努力将对模板的使用控制在一个合理的水平,但我们必须得承认,正是对模板的支持使得C++具有“自我修复”的能力,而这也是本书得以诞生的主要原因。

由于灵活性和实用性对我而言非常重要,因此书中的代码并非只能在少数最新编译器上编译;实际上,书中几乎所有代码都可以在任意一款“还算可以”的现代编译器(见附录A)上编译。当然,有一些很好的编译器是可以免费获得的,并且你也可以相信你的编译器能够编译这些代码。

只要有可能,我就会尽量避免涉及特定的操作环境、库和技术。然而我也略微谈到了一些,所以,了解以下内容将会有所帮助(尽管并非必不可少):COM和CORBA、动态库(UNIX和Win32的)、STL、线程(POSIX和Win32的)、UNIX以及Win32。参考书目中包含有许多这些方面以及其他方面内容的好书。此外,熟悉不止一种机器架构也是有帮助的,当然这同样并非不可或缺。

由于C目前仍是语言间交互以及操作系统开发的通用语言,因此它继续作为一门极其重要的语言存在着。尽管本书是关于C++的,但在某些领域,C跟C++之间的共性会变得很重要,我认为在这些领域选择兼顾C/C++是合理的。事实上,正如我们将在本书的第二部分中看到的,我们有时需要求助于C来支持C++的一些高级用法。

此外,我还作了一个重要的假定。我假定你们也认为工作的质量是非常重要的,并且有动力去寻找达到这一目标的新途径。本书不敢妄称是这些所谓新途径的惟一源泉。确切地说,它提供了一种实践性的、有时甚至是异端的视角来看待我们在C++中遇到的问题。如果情况够好的话,本书或许也能成为你的精华书库中的成员之一。最终的责任落在你自己的肩上,剩下来要做的就是去寻找最好的工具来支持你的工作。

本书的组织方式

本书的主要内容分为6个部分,每一部分由一个绪论和5~7章组成,每一章又可以被进一步划分为若干节。

既然本书取名为“Imperfect C++”,那么我就会在书中尽量突显出实际的不完美之处,这就是你们在本书的通篇都会发现一些所谓的“不完美(Imperfection)”的原因。在书的前几部分,这些不完美之处出现得比较密集,这说明它们自身和它们的解决之道尚且是比较简单的。每个小节都对应着语言的某个特定的特性,并且通常会介绍它的一个不完美之处。只要有可能,我就会提供一些具体的技巧或技术来解决这些问题,或至少为开发者提供控制问题的方法。随着本书内容逐步展开,这些不完美之处将会变得不再像前面那样散碎,显得更为重大,从而伴随有更大篇幅、更加详细的讨论。

本书并没有采用时髦的“自助餐”式的写法,也不存在一条必须从头读到尾的贯穿全书的主线。当然,大部分后续章节的内容是根据前面章节的内容进行描述的,有时甚至建立在之前的章节之上,所以除非你故意作对,否则最好还是按顺序阅读。然而,一旦你读完一遍后,回头再来参考其中的某些部分时,你就可以根据需要跳至任意一处而不再需要通读所有内容了。在每一章中,各节一般是按内容顺序排列的,所以我建议你也应该按顺序来阅读每一节。

在难度方面,第一部分到第四部分显然经历了一个从易到难的过程,从相当简单明了直到有相当高的要求。 尽管第五部分和第六部分需要依赖第三部分和第四部分的一些内容,但它们相对来说不再那么具有挑战性了。你可以优哉游哉地一直读到附录。

主要内容介绍完之后是4个简短的附录。附录A介绍在探讨本书各项议题时使用的编译器和库的详细信息。附录B向你展示一个年轻的C++工程师在刚踏入这一充满陷阱的领域时所犯下的一些令人目瞪口呆的错误。附录C介绍Arturius 项目,这是一个免费的源码开放的编译器多路分发器,你也可以在随书光盘中找到它。最后,附录D介绍随书光盘的内容。

我的编码风格十分一致,甚至可以说是严格,你也可以说它过于“学究气”,我以前的同事和使用我库的人们早就这样说过。但我之所以采取这种风格是因为这么一来代码中的所有东西都有其明确的位置,人家不至于会问“某某东西到哪里去了”这种问题,同时这也意味着当我几年后重新面对这些代码时,我还可以轻松搞定它。当然这么做也有缺点:我需要一个21英寸的显示器和一个工业用激光打印机。

为了尽量减少我的编码风格对阅读本书的影响,我在书中出现的代码示例中使用了一些自由风格。你将会在示例中看到很多省略号(...),它们一般表示前面的有关例子中已经包含了该段代码,或者表示这些省却的代码是我们司空见惯的样板式代码(例如,禁止客户代码访问某些方法,见2.2节)。只有编码风格中对可靠性有着显著影响的方面才会被加以讨论(见第17章)。

参考资料

我在阅读其他C++书籍时感到不满的一件事是:作者指出事实的同时从不提及标准的相关部分。所以我在写作本书的过程中,除了会不断引用一些相关的书籍和文章外,还会在描述C++语言行为的同时提供其在C++(C++98)或C(C99)标准中的相关参考。

补充材料

光盘

随书光盘中包含有一些库、编译器(包括书中描述的大量编码技术)、测试程序、工具,以及其他有用的软件,另外还有许多摘自各种出版物的相关文章。关于光盘的详细内容,请参考附录D。

网上资源

致谢

在几乎所有你看到或将要看到的书籍当中,你都会发现其中有一页或几页充满着对家人和朋友热情洋溢的致谢之辞,我可以向你保证这些言辞都是发自内心的真情流露。一本书要想得以完成,其背后必定隐藏着若干人的支持。

首先感谢我的母亲和Suzanne,感谢她们长期以来的容忍、支持以及养育之恩,直到当年的唧唧喳喳的小布谷鸟到了早就成熟的年龄(27岁),才离开温暖的巢,飞向一个不同的世界。感谢母亲和Robert在一段艰苦但最终有所收获的岁月里一直帮助小布谷鸟和他的家庭。尤其感谢Robert在这段时间里的许多重要时刻帮我保持精神放松。

谢谢Piker填补了这个大家庭的空缺,并且不遗余力地照看孩子,鼓励我们,并提供免费的午餐。同样感谢Dazzle,他总是告诉我他对我极有信心,并难能可贵地放弃那些诱人的DBA大师活动,坚定地帮我做那些沉闷的审稿工作;他在看其他Perl和Python脚本的时候可决不会是这个心态!也要感谢Besso一直以来对我的计划的浓厚兴趣、过分的自豪以及鼓舞人心的观点。谢谢Al和Cynth(亲家)提供许多免费的饭菜和美味的巧克力(哦,我差点忘了我那辆自行车……)。

衷心感谢808 State、Aim、Barry While、Billy Bragg、De La Soul、Fatboy Slim、George Michael、Level 42、Rush、Seal、Stevie Wonder以及The Brand New Heavies,没有他们我不可能从这个一年半的幻想中挣扎过来。

最重要的感谢要给予我的美丽爱妻Sarah,感谢她抑制住合乎情理的担心和疑虑,而表现出完全的支持和信任。她是我心目中真正的明星!

感谢一些出色的人,他们对我的教育和事业的影响是深远的。感谢Bob Cryan教授,感谢他能够赏识一名天赋不错的学生,并在后来3年的研究生在读期间宽容他的逃课(去骑自行车)。

还要感谢Richard McCormack让我保持在概念上的优雅之外还看到了代码的高效之美。这段时间我有时会被别人责备说过于看重效率了,我就说你要怪就怪Richard去吧。另外,感谢Graham Jones(绰号“Dukey”)教我设置vi,在那疯狂的6个月的时间里和我保持深厚的友谊以及提供开心的玩笑。这些东西,无可替代!

同样还要感谢Leigh和Scott Perry,感谢他们向我介绍“螺栓”概念以及其他优秀的技术。

特别感谢Andy Thurling。在我怀揣博士文凭和名不副实的软件工程技能等级证书去找工作时,Andy对我的潜能表现出充分的信心。 Andy还教给我或许在这个奇妙而令人畏惧的职业中最最重要的一课:“我们只是在尽量充分利用手头拥有的信息而已(Skegging it Out)”。 Chuck Allison则以更为亲切的形式来表述这个意思,那是一句来自古老的印第安人部落中的箴言:“向一个不断学习的人学知识就好比是在饮一条生生不息的河流”。

任何书籍的成功都离不开出版社、评审者以及其他给出指导和建议的人们的帮助。感谢我的编辑Peter Gordon给予鼓励并包容一个热情而任性的作者在写他的第一本书的过程中情绪起落。同样感谢Peter的得力助手Bernard Gaffney,他很好地控制了整个计划进程,并耐心地答复我每天发去的几封电子邮件。还要感谢Addison Wesley出版社的产品和市场部门的其他职员,包括Amy Fleischer、Chanda Leary-Coutu、Heather Mullane、Jacquelyn Doucette、Jennifer Andrews、Kim Boedigheimer以及Kristy Hart。衷心感谢(并致歉)我的项目经理Jessica Balch不厌其烦地帮助我纠正书中糟糕的句法、蹩脚的幽默以及英式英语的拼写(例如有很多“ize”被写成了“ise”)。还要特别感谢Debbie Lafferty,2002年的某一个晚上我在睡梦中冒出了“Imperfect C++”这个念头,是Debbie Lafferty鼓励我付诸实现的。

感谢忠诚的评审者们,他们是Chuck Allison、Dave Brooks、Darren Lynch、Duane Yates、Eugene Gershnik、Gary Pennington、George Frasier、Greg Peet、John Torjo、Scott Patterson以及Walter Bright。没有他们我肯定会到处磕磕碰碰,踉踉跄跄。他们中的一些人让我保持心情愉快,有些人则使我质疑这个写作计划是否明智,但无论如何他们的反馈信息都极大地有助于我改善最终的成果。我们生活在一个奇妙的世界中,来自各个不同国家的人们可以建立起友谊,虽然其中大部分人我未曾谋面,却能够给予我如此之多的帮助,这真是奇妙!

同样要感谢Addison Wesley的审阅者们,包括Dan Saks、JC van Winkel、Jay Roy、Ron McCarty、Justin Shaw、Nevin Liber以及Steve Clamage。他们的反馈信息对于本书的篇幅能够降到1000页以下起到了至关重要的作用,而且帮助我避免了一些无聊的闲话和粗心大意的错误。作为一名作者,我早已领略了写作和审稿过程的艰辛,我知道一次彻底的审阅需要付出多少精力,真的非常感谢他们投入的时间和精力。

感谢Peter Dimov允许我引用他的名言(在第26章),同时还对第五部分各章给出了极好的建议。感谢Kevlin Henney对第19章和智能强制的一些有趣的讨论所给予的关注。感谢Joe Goodman仔细审阅有关C++ ABI的那一部分(第7、8两章),使我最终能够呈上一份像样的讨论。感谢Thorsten Ottosen在第1章有关契约式设计部分提供的类似的帮助。

特别感谢Chuck Allison、Herb Sutter、Joe Casad、John Dorsey以及Jon Erickson,他们在过去的几年中在各方面都给予我极大的支持和鼓励。

感谢Bjarne Stroustrup的鼓励,他还不时为我补上一点历史常识。哦,首先还是要感谢他发明了这门神奇的语言!

感谢Walter Bright在本书的写作过程中持续不断地改进他的优秀的Digital Mars C/C++编译器,在世界上最缺乏耐心的家伙持续的质问面前保持责任心,而且还友好地将我引领入D语言开发世界,后者也给我这本书的写作带来了不少灵感。同样感谢Greg Comeau,尽管他用不着对他的Comeau编译器做那么多的改进:Comeau是目前业界最遵从标准的C++编译器!他们除了是优秀而又反应迅速的编译器供应者之外,还在众多问题上持续不断地给予鼓励、建议以及其他信息。

感谢CMP出版公司允许我在书中使用我原先在他们刊物上发表的文章中的一些内容,并允许我将原先的几篇文章放在随书光盘中(见附录D)。

感谢Borland、CodePlay、Digital Mars、Intel、Metrowerks以及Microsoft公司为我的研究、写作以及编写开源库提供编译器。

特别要感谢Digital Mars、Intel和Watcom公司授权我将他们的编译器放在随书光盘中(见附录D)。另外,Greg Peet在光盘的设计及内容方面的巨大帮助值得大大嘉赏。

谢谢C/C++ User's Journal、Dr. Dobb's Journal、BYTE以及Windows Developer Network的读者,他们为我的文章和专栏友好地提供了反馈信息和支持。

同样感谢整个C++社群,以及那些关注各种与C++有关的新闻组(见附录A)的好心人。他们是Attila Feher、Carl Young、Daniel Spangenberg、Eelis van der Weegen、Gabriel Dos Reis、Igor Tandetnik、John Potter、Massimiliano Alberti、Michal Necasek、Richard Smith、Ron Crane、Steven Keuchel、Thomas Richter以及“tom_usenet”,而且或许还有好些人没有列出。尤其感谢Ilya Minkov,是他要求我为STLSoft库增加属性(Properties)实现的,而我自己以前可没有产生过这个念头。如果不是因为这个建议,我可能永远也不会实现这项我钟爱的技术(见第35章)。

最后,还要感谢STLSoft库的所有用户,没有他们的信息反馈,这个库中的许多特性就不会存在,而且本书中的某些部分也会变得难弄得多。

Matthew Wilson

Specifications

Brand Jingdong book
Brand Origin China

Disclaimer

Product packaging, specifications and price are subject to change without notice. All information about the products on our website is provided for information purposes only. Please always read labels, warnings and directions provided with the product before use.

View Full Terms of Use
Add to favorites
{{ $isZh ? coupon.coupon_name_sub : coupon.coupon_ename_sub | formatCurrency }}
{{__("Buy Directly")}} {{ itemCurrency }}{{ item.directly_price }}
Quantity
{{ quantity }}
{{ instockMsg }}
{{ limitText }}
{{buttonTypePin == 3 ? __("Scan to view more PinGo") : __("Scan to start")}}
Sold by JD@CHINA
Ship to
{{ __("Ship to United States only") }}
Free shipping over 69
Genuine guarantee

Added to Cart

Keep Shopping

More to Consider

{{ item.brand_name }}

{{ item.item_name }}

{{ item.currency }}{{ item.market_price }}

{{ item.currency }}{{ item.unit_price }}

{{ item.currency }}{{ item.unit_price }}

Coupons

{{ coupon.coupon_name_new | formatCurrency }}
Clip Clipped Over
{{ getCouponDescStr(coupon) }}
{{ coupon.use_time_desc }}
Expires soon {{ formatTime(coupon.use_end_time) }}

Share this item with friends

Cancel

Yami Gift Card

Get this exclusive deal when paying with gift card

Terms and Conditions

Gift card deals are special offers for selected products;

The gift card deals will automatically be activated if a customer uses gift card balance at check out and the balance is sufficient to pay for the total price of the shopping cart products with gift card deals;

You will not be able to activate the gift card deals if you choose other payment methods besides gift card. The products will be purchased at their normal prices;

If your account balance is not enough to pay for the products with gift card deals, you can choose to reload your gift card balance by clicking on the Reload button at either shopping cart page or check out page;

Products that have gift card deals can be recognized by a special symbol showing 'GC Deal';

For any additional questions or concerns, please contact our customer service;

Yamibuy reserves the right of final interpretation.

Sold by Yami

Service Guarantee

Yami Free Shipping over $49
Yami Easy Returns
Yami Ships from United States

Shipping

  • United States

    Standard Shipping is $5.99 (Excluding Alaska & Hawaii). Free on orders of $49 or more.

    Local Express is $5.99 (Available in Parts of CA, NJ, MA & PA). Free on orders of $49 or more.

    2-Day Express (Includes Alaska & Hawaii) starts at $19.99.

Return Policy

Yami is committed to provide our customers with a peace of mind when purchasing from us. Most items shipped from Yamibuy.com can be returned within 30 days of receipt of shipment (For Food, Beverages, Snacks, Dry Goods, Health supplements, Fresh Grocery and Perishables Goods, within 7 days of receipt of shipment due to damages or quality issues; To ensure that every customer receives safe and high-quality products, we do not provide refunds or returns for beauty products once they have been opened or used, except in the case of quality issues; Some products may have different policies or requirements associated with them, please see below for products under special categories, or contact Yami Customer Service for further assistance).
Thank you for your understanding and support.

Learn More

Sold by Yami

Terms and Conditions of Yami E-Gift Card

If you choose “Redeem automatically” as your delivery method, your gift card balance will be reload automatically after your order has been processed successfully;

If you choose “Send to Email”as your delivery method, the card number and CVV will be sent to the email address automatically;

Any user can use the card number and CVV to redeem the gift card, please keep your gift card information safely. If you have any trouble receiving email, please contact Yami customer service;

Yami gift card can be used to purchase both Yami owned or Marketplace products;

Yami gift card will never expire;

Yami gift card balance does not have to be used up at once;

All rights reserved by Yami.

Return Policy

Gift card that has already been consumed is non-refundable.

Sold by JD@CHINA

Service Guarantee

Yami Free Shipping over $49
Yami Easy Returns
Yami Ships from United States

Shipping

  • United States

    Standard Shipping is $5.99 (Excluding Alaska & Hawaii). Free on orders of $49 or more.

    Local Express is $5.99 (Available in Parts of CA, NJ, MA & PA). Free on orders of $49 or more.

    2-Day Express (Includes Alaska & Hawaii) starts at $19.99.

Return Policy

You may return product within 30 days upon receiving the product. Items returned must be new in it's original packing, including the original invoice for the purchase. Customer return product at their own expense.

Sold by JD@CHINA

Service Guarantee

Yami Cross-store Free Shipping over $69
Yami 30-days Return

Yami-China FC

Yami has a consolidation warehouse in China which collects multiple sellers’ packages and combines to one order. Our Yami consolidation warehouse will directly ship the packages to your door. Cross-store free shipping over $69.

Return Policy

You may return products within 30 days upon receiving the products. Sellers take responsibilities for any wrong shipment or missing items. Packing needs to be unopened for any other than quality issues return. We promise to pack carefully, but because goods are taking long journey to destinations, simple damages to packaging may occur. Any damages not causing internal goods quality problems are not allowed to return. If you open the package and any quality problem is found, please contact customer service within three days after receipt of goods.

Shipping Information

Yami Consolidation Service Shipping Fee $9.99(Free shipping over $69)

Sellers in China will ship their orders within 1-2 business days once the order is placed. Packages are sent to our consolidation warehouse in China and combined there. Our Yami consolidation warehouse will directly ship the packages to you via UPS. The average time for UPS to ship from China to the United States is about 10 working days and it can be traced using the tracking number. Due to the pandemic, the delivery time may be delayed by about 5 days. The package needs to be signed by the guest. If the receipt is not signed, the customer shall bear the risk of loss of the package.

Sold by JD@CHINA

Service Guarantee

Free shipping over 69
Genuine guarantee

Shipping

Yami Consolidated Shipping $9.99(Free shipping over $69)


Seller will ship the orders within 1-2 business days. The logistics time limit is expected to be 7-15 working days. In case of customs clearance, the delivery time will be extended by 3-7 days. The final receipt date is subject to the information of the postal company.

Yami Points information

All items are excluding from any promotion or points events on Yamibuy.com

Return Policy

You may return product within 30 days upon receiving the product. Items returned must be new in it's original packing, including the original invoice for the purchase. Customer return product at their own expense.

Yami

Download the Yami App

Back Top

Recommended for You

About the brand

Jingdong book

为您推荐

Yami
欣葉
2种选择
欣叶 御大福 芋头麻薯 180g

周销量 600+

$1.66 $1.99 83折
Yami
欣葉
2种选择
欣叶 御大福 芋头麻薯 180g

周销量 600+

$1.66 $1.99 83折
Yami
欣葉
2种选择
欣叶 御大福 芋头麻薯 180g

周销量 600+

$1.66 $1.99 83折
Yami
欣葉
2种选择
欣叶 御大福 芋头麻薯 180g

周销量 600+

$1.66 $1.99 83折
Yami
欣葉
2种选择
欣叶 御大福 芋头麻薯 180g

周销量 600+

$1.66 $1.99 83折
Yami
欣葉
2种选择
欣叶 御大福 芋头麻薯 180g

周销量 600+

$1.66 $1.99 83折

Reviews{{'('+ commentList.posts_count + ')'}}

Have your say. Be the first to help other guests.

Write a review
{{ totalRating }} Write a review
  • {{i}} star

    {{i}} stars

    {{ parseInt(commentRatingList[i]) }}%

Yami Yami
{{ comment.user_name }}

{{ showTranslate(comment) }}Show Less

{{ strLimit(comment,800) }}Show more

Show Original

{{ comment.content }}

Yami
Show All

{{ formatTime(comment.in_dtm) }} VERIFIED PURCHASE {{groupData}}

{{ comment.likes_count }} {{ comment.likes_count }} {{ comment.reply_count }} {{comment.in_user==uid ? __('Delete') : __('Report')}}
Yami Yami
{{ comment.user_name }}

{{ showTranslate(comment) }}Show Less

{{ strLimit(comment,800) }}Show more

Show Original

{{ comment.content }}

Yami
Show All

{{ formatTime(comment.in_dtm) }} VERIFIED PURCHASE {{groupData}}

{{ comment.likes_count }} {{ comment.likes_count }} {{ comment.reply_count }} {{comment.in_user==uid ? __('Delete') : __('Report')}}

No related comment~

Review

Yami Yami

{{ showTranslate(commentDetails) }}Show Less

{{ strLimit(commentDetails,800) }}Show more

Show Original

{{ commentDetails.content }}

Yami
Show All

{{ formatTime(commentDetails.in_dtm) }} VERIFIED PURCHASE {{groupData}}

{{ commentDetails.likes_count }} {{ commentDetails.likes_count }} {{ commentDetails.reply_count }} {{commentDetails.in_user==uid ? __('Delete') : __('Report')}}

Please write at least one word

Comments{{'(' + replyList.length + ')'}}

Yami Yami

{{ showTranslate(reply) }}Show Less

{{ strLimit(reply,800) }}Show more

Show Original

{{ reply.reply_content }}

{{ formatTime(reply.reply_in_dtm) }}

{{ reply.reply_likes_count }} {{ reply.reply_likes_count }} {{ reply.reply_reply_count }} {{reply.reply_in_user==uid ? __('Delete') : __('Report')}}

Please write at least one word

Cancel

That’s all the comments so far!

Write a review
How would you rate this item?

Please add your comment.

  • A nice nickname will make your comments more popular!
  • The nickname in your account will be changed to the same as here.
Thanks for your review
Our community rely on great reviews like yours to find the best of Asia.

Report

If you find this content inappropriate and think it should be removed from the Yami.com site, let us know please.

Cancel

Are you sure to delete your review?

Cancel

You’ve Recently Viewed

About the brand

Jingdong book