02 2012 档案

摘要:高质量,源码开放、平台独立、编译器独立的程序库。 http://boost.org,它和c++标准委员会之间有着独一无二的密切关系,并对委员会深具影响力。它以公开进行的同僚复审(public peer review)为基础接纳程序库。 boost对付的主题非常繁多,包括: 字符串与文本处理, 容器, 函数对象和高级编程, lambda,可以让我们轻松的随时随地创建函... 阅读全文
posted @ 2012-02-20 10:53 lidan 阅读(459) 评论(0) 推荐(0)
摘要:c++Standard——定义c++语言及其标准程序库的规范,TR1详细叙述了14个新组件,都放在std命名空间内c++98列入的c++标准程序库有哪些主要成分:stl,覆盖容器、迭代器、算法、函数对象、各种容器适配器和函数对象适配器。Iostreams,覆盖用户自定缓冲功能,国际化I/o,以及预先定义的对象cin,cout,cerr和clog国际化支持,包括多区域能力。像wchar_t和wstring(由wchar_ts组成的strings)都对促进Unicode有所帮组。数值处理,包括复数模板(complex)和纯数值数组(valarray)。异常阶层体系(exception hierar 阅读全文
posted @ 2012-02-20 10:43 lidan 阅读(1250) 评论(0) 推荐(0)
摘要:class B{ public: virtual void f() const; }; class D: public B{ public: virtual void f(); }; 这里希望重新定义virtual函数B::f,但有个错误,B中的f是个const成员函数,但D中未被声明const。有编译器就这样说: warning:D... 阅读全文
posted @ 2012-02-19 23:58 lidan 阅读(274) 评论(0) 推荐(0)
摘要:Widget* pw = new Widget; 共有两个函数被调用:一个分配内存的operator new,一个Widget的default构造函数。 假设第一个调用成功,第二个却抛出异常。步骤一所分配内存必须取消并恢复旧观,否则会造成内存泄漏。这时,客户没能力归还内存,因为Widget构造函数抛出异常,pw尚未被赋值,客户手上也就没有指针指向该被归还的内存。取消步骤一,并恢复旧观... 阅读全文
posted @ 2012-02-19 23:01 lidan 阅读(1246) 评论(0) 推荐(0)
摘要:实现一致性operator new必须返回正确的值,内存不足时必须调用new_handling函数,必须有对付零内存的准备,还需要避免不慎掩盖正常形式的new。 void* operator new(std::size_t size) throw(std::bad_alloc) { using namespace std; if (size ==... 阅读全文
posted @ 2012-02-19 20:45 lidan 阅读(441) 评论(0) 推荐(0)
摘要:为什么有人想要替换operator new 和 operator delete呢?三个常见的理由: 1.用来检测运用上的错误。 如果将“new所的内存”delete却不幸失败,会导致内存泄漏。如果在“new所得内存”身上多次delete会导致不确定行为。如果new持有一串动态分配的所得地址,operator delete将地址从中移走,倒是很容易检测出上述错误用法。此外各式各样的编程错误... 阅读全文
posted @ 2012-02-19 10:45 lidan 阅读(1241) 评论(0) 推荐(0)
摘要:当operator new无法满足某一内存分配需求时,会抛出异常。再抛出异常以反映一个未获满足的内存需求之前,它会先调用客户指定的错误处理函数,new-handler。为了指定这个“用以处理内存不足”的函数,客户必须调用set-new-handler,那是声明于<new>的一个标准函数库函数: namespace std{ typedef void (*new_handle... 阅读全文
posted @ 2012-02-18 22:27 lidan 阅读(1328) 评论(0) 推荐(0)
摘要:template metaprogramming(模板元编程)是编写template-based c++程序并执行于编译期的过程。是以c++写成,执行于c++编译器内的程序。一旦tmp程序执行结束,其输出,也就是template具现出来的若干c++源码,便会一如往常的编译。 tmp有两个伟大的效力。第一,它让某些事情更容易。如果没有它,那些事情将是困难的,甚至是不可能的。第二,由于tmp执... 阅读全文
posted @ 2012-02-17 22:52 lidan 阅读(400) 评论(0) 推荐(0)
摘要:stl主要由“用以表现容器、迭代器和算法”的template构成,但也覆盖若干工具性的templates,其中一个名为advance,将某个迭代器移动某个给定距离: template<typename IterT, typename DistT> void advance(IterT& iter, DistT d); //将迭代器向前移动d个单位,d<0则向后移动。 st... 阅读全文
posted @ 2012-02-17 17:08 lidan 阅读(525) 评论(0) 推荐(0)
摘要:条款24说过为什么惟有non-member函数才有能力“在所有实参身上实施隐式类型转换”。本条款将Rational和operator*模板化: template<typename T> class Rational{ Rational(const T& number = 0, const T& denominator = 1); ... 阅读全文
posted @ 2012-02-16 22:57 lidan 阅读(558) 评论(0) 推荐(0)
摘要:所谓智能指针是“行为像指针”的对象,并提供指针没有的机能。 真实指针做的很好的一件事是,支持隐式转换。Derived class指针可以隐式转换为base class指针。指向non-const的对象的指针可以转换为指向const对象。下面是发生于三层继承体系的一些转换: class Top{...}; class Middle: public Top{...}; ... 阅读全文
posted @ 2012-02-15 22:41 lidan 阅读(484) 评论(0) 推荐(0)
摘要:template是节省时间和避免重复代码的一个奇妙方法。class template的成员函数只有在被使用时才被暗中具现化。function templates有类似的诉求。 但是如果你不小心,使用templates可能导致代码膨胀(code bloat):其二进制代码带着重复(或几乎重复)的代码、数据、或两者。其结果可能源码看起来合身整齐,但目标码却不是那么回事。你需要知道如何避免这样的... 阅读全文
posted @ 2012-02-15 20:50 lidan 阅读(522) 评论(0) 推荐(0)
摘要:我们需要一个程序,传送信息到不同的公司去。信息要不译成密码,要不就是未加工的文字。如果编译期间我们有足够信息来决定哪一个信息传至那一家公司,就可以采用基于template的解法: class CompanyA{ public: void sendCleartext(const std::string& msg); void sendEncrypt... 阅读全文
posted @ 2012-02-15 15:02 lidan 阅读(477) 评论(0) 推荐(0)
摘要:template声明式中,class和typename这两个关键字意义完全相同 template<class T> class Widget; template<typename T> class Widget; 有时候你一定要用typename, 可以在template中指涉的两种名称: template <typename C> void print2n... 阅读全文
posted @ 2012-02-14 21:08 lidan 阅读(824) 评论(0) 推荐(0)
摘要:面向对象编程世界总是以显示接口(explicit interface)和运行期多态(runtime polymorphism)解决问题。 class Widget{ public: Widget(); virtual ~Widget(); virtual std::size_t size() const; vi... 阅读全文
posted @ 2012-02-14 17:27 lidan 阅读(554) 评论(0) 推荐(0)
摘要:一旦涉及多重继承(multiple inheritance;MI): 程序有可能从一个以上的base class继承相同名称(如函数、typedef等)。那会导致较多的歧义机会。例如: class BorrowableItem { public: void checkOut(); }; class ElectronicGadet { p... 阅读全文
posted @ 2012-02-14 15:53 lidan 阅读(531) 评论(0) 推荐(0)
摘要:c++中public继承视为is-a关系。现在看private继承: class Person{...}; class Student: private Person {...}; void eat(const Person& p); void study(const Student& s); Person p; Student s; e... 阅读全文
posted @ 2012-02-14 10:39 lidan 阅读(661) 评论(0) 推荐(0)
摘要:复合(composition)是类型之间的一种关系,当某种类型的对象内含它种类型的对象,便是这种关系: class Address {...}; class PhoneNumber {...}; class Person { public: ... private: std::string name;//合成成分物 ... 阅读全文
posted @ 2012-02-12 20:36 lidan 阅读(491) 评论(0) 推荐(0)
摘要:重新定义一个继承而来的non-virtual函数永远都是错误的,本条款的讨论限制在“带有缺省参数的virtual函数”。 virtual函数是动态绑定的,而缺省参数却是静态绑定。 对象的所谓静态类型,是它在程序中被声明时所采用的类型。 class Shape { public: enum ShapeColor {Red, Green, Blue}; ... 阅读全文
posted @ 2012-02-11 20:53 lidan 阅读(520) 评论(0) 推荐(0)
摘要:class B { public: void mf(); ... }; class D : public B {...}; D x; 如果一下行为: B* pB = &x; pB->mf(); 异于以下行为: D* pD = &x; pD->mf(); 你可能相当惊讶。两者的行为确实应该相同,但是如果mf... 阅读全文
posted @ 2012-02-11 17:09 lidan 阅读(421) 评论(0) 推荐(0)
摘要:假设你整在写一个视频游戏软件,由于不同的人物可能以不同的方式计算它们的健康指数,将healthValue声明为virtual似乎再明白不过的做法:class GameCharacter { public: virtual int healthValue()const; ... };由于这个设计如此明显,你可能没有认真考虑其他替代方案。为了帮助你跳脱面向对象设计路上的常轨,让我们考虑其他一些解法:藉由Non-virtual interface手法实现Template Method模式有个思想流派主张virtual函数应该几乎总是private。他们建议,较好的设计是保留healthValue.. 阅读全文
posted @ 2012-02-10 22:32 lidan 阅读(611) 评论(0) 推荐(0)
摘要:身为class设计者,有时候你希望derived class只继承成员函数的接口(也就是声明):有时候你又希望derived class同时继承函数的 接口和实现,但又希望能够覆写(override)它们所继承的实现:又有时候你希望derived class同时继承函数的接口与实现,并且不允许覆写任何东西。 让我们考虑一个展现绘图程序中各种几何形状的class继承体系: cla... 阅读全文
posted @ 2012-02-10 14:37 lidan 阅读(811) 评论(0) 推荐(1)
摘要:这个题材其实和继承无关,而是和作用域(scopes)有关。 int x; void someFunc() { double x; std::cin >> x; } 这个指涉的是local变量x,而不是global变量x,因为内存作用域会的名称遮掩外围作用域的名称。 当编译器处于someFunc的作用域内并遭遇名称x... 阅读全文
posted @ 2012-02-09 21:38 lidan 阅读(410) 评论(0) 推荐(0)
摘要:如果你令class D以public形式继承class B,你便是告诉c++编译器,每一个类型为D的对象同时也是一个类型为B的对象,反之不成立。 B比D表现出更一般化的概念,D比B更特殊化的概念。任何函数如果期望获得一个类型为B(或pointer to B或reference-to-B)的实参,都也愿意接受一个D对象(或pointer-to-D或reference-to-D)。这个论点只有... 阅读全文
posted @ 2012-02-09 19:56 lidan 阅读(421) 评论(0) 推荐(0)
摘要:假设你对c++程序的某个class实现文件做了些轻微改变,修改的不是接口,而是实现,而且只改private成分。 然后重新建置这个程序,并预计只花数秒就好,当按下“Build”或键入make,会大吃一惊,因为你意识到整个世界都被重新编译和链接了! 问题是在c++并没有把“将接口从实现中分离”做得很好。class 的定义式不只详细叙述了class接口,还包括十足的实现细目: cl... 阅读全文
posted @ 2012-02-05 22:51 lidan 阅读(1061) 评论(0) 推荐(0)
摘要:inline函数,可以调用它们而又不需蒙受函数调用所招致的额外开销 当你inline某个函数,或许编译器就因此又能力对它(函数本体)执行语境相关最优化。 然而,inline函数背后的整体观念是,将“对此函数的每一个调用”都已函数本体替换之,这样做可能增加你的目标码(object code)大小。在内存有限的机器上,过度inline会造成程序体积太大,导致换页行为,降低缓存的命中率... 阅读全文
posted @ 2012-02-04 23:43 lidan 阅读(546) 评论(0) 推荐(0)
摘要:有个class用来表现夹带背景图案的GUI菜单单,这个class用于多线程环境: class PrettyMenu{ public: ... void changeBackground(std::istream& imgSrc); ... private: Mutex mutex; ... 阅读全文
posted @ 2012-02-03 15:20 lidan 阅读(746) 评论(0) 推荐(0)
摘要:假设程序涉及矩形。为了让Rectangle对象尽可能小,可能把定义矩形的点放在一个辅助的struct内再让Rectangle去指它: class Point{ public: Point(int x, int y); ... void setX(int newVal); void setY(int newVal... 阅读全文
posted @ 2012-02-02 16:22 lidan 阅读(442) 评论(0) 推荐(0)
摘要:转型(casts)破坏了类型系统(type system)。可能导致任何类型的麻烦。c++提供四种新式转型const_cast<T>(expression) //cast away the constnessdynamic_cast<T>(expression) //safe downcasting安全向下转型reinterpret_cast<T>(expression)//意图执行低级转型,实际动作(及结果)可能取决于编译器,这也表示它不可移植;低级代码以外很少见static_cast<T>(expression)//用来强迫隐式转换(impl 阅读全文
posted @ 2012-02-02 14:13 lidan 阅读(449) 评论(0) 推荐(0)