
Effective C++
It_Ds_N_cpp
这个作者很懒,什么都没留下…
展开
-
Effective C++ 条款 52:写了placement new也要写placement delete
(一)当我们写下了下面这个语句:Widget* pw = new Widget;这个时候,共有两个函数被调用:一个分配内存的operator new,另外一个是Widget的default构造函数。假设第一个调用成功,第二个却抛出异常。步骤一所分配内存必须取消并恢复旧观,否则会造成内存泄漏。这时,客户没能力归还内存,因为Widget构造函数抛出异常,pw尚未被赋值,客户手上原创 2014-09-29 21:25:34 · 644 阅读 · 0 评论 -
Effective C++:条款23:宁以non-member、non-friend替换member函数
(一)有个class来表示网页浏览器:class WebBrowser { public: void clearChache(); void clearHistory(); void removeCookies(); };许多用户会想一整个执行所有这些动作,因此WebBrowser也提供这样一个函数:clearEverythingclass原创 2014-06-19 15:34:56 · 774 阅读 · 0 评论 -
Effective C++:条款22:将成员变量声明为private
(一)为什么不采用public成员变量(1)首先,从语法一致性考虑,客户唯一能访问对象的方法就是通过成员函数,客户不必考虑是否该记住使用小括号()。(2)其次,使用函数可以让我们对成员变量的处理有更精确的控制。如果我们令成员变量为public,那么每个人都可以读写它!但如果我们以函数取得或设定其值,我们就可以实现出“不准访问”、“只读访问”以及“读写访问”,我们甚至可以实现“惟写访原创 2014-06-19 13:13:29 · 913 阅读 · 0 评论 -
Effective C++:条款21:必须返回对象时别妄想返回其reference
(一)一定要避免传递一些references去指向其实并不存在的对象。看下面这个类:class Rational { public: Rational(int numerator = 0, int denominator = 1); private: int n, d; friend const Rational operator*(const Rat原创 2014-06-15 19:54:33 · 696 阅读 · 0 评论 -
Effective C++:条款38:通过复合塑模出has-a或“根据某物实现出”
(一)public继承是“is-a“的关系,而复合有”has-a“或”根据某物实现出(is-implemented-in-terms-of)“的意思——当复合发生在应用域内的对象之间,表现出has-a关系;当它发生于实现域内则是表示“根据某物实现出”的关系。应用域部分,相当于你塑造的世界中的某些事物,例如人,汽车等。后者的对象则是实现细节人工产品(这产品现实世界中是没有的),像什么原创 2014-07-04 18:46:18 · 923 阅读 · 0 评论 -
Effective C++:条款20:宁以 pass-by-reference-to-const替换pass-by-value
(一)调用函数的时候如果传递参数pass-by-value,那么函数参数都是以实际实参的副本为初值,调用端所获得的亦是函数返回值的一个复件。看下面代码:class Person { public: Person(); virtual ~Person(); private: string name; string address; };原创 2014-06-15 14:19:13 · 943 阅读 · 0 评论 -
Effective C++:条款40:明智而审慎地使用多重继承
(一) 慎用多重继承,因为那样的话可能会造成歧义。。class BorrowableItem { public: void checkOut(); };class ElectronicGadet { private: bool checkOut() const; };class MP3Player : public BorrowableItem原创 2014-07-07 11:57:41 · 860 阅读 · 0 评论 -
Effective C++:条款39:明智而审慎地使用private继承
(一)(1)private继承意味着“根据某物实现出”,只有实现部分被继承,接口部分应略去;(2)它只在软件“实现”层面上有意义,在软件“设计”层面上没有意义。(3)private继承而来的基类成员都会在派生类中成为private属性,纵使它们在base class中原本是protected或public属性;(4)如果类之间是private继承关系,编译器不会自动将一个派生类对象原创 2014-07-06 17:54:17 · 855 阅读 · 0 评论 -
Effective C++:条款37:绝不重新定义继承而来的缺省参数值
由于重新定义继承而来的non-virtual函数是不正确的(见上一个条款),所以这个条款就将问题局限于:绝不重新定义继承一个带有缺省参数值的virtual函数。(一)virtual函数是动态绑定的,而缺省参数却是静态绑定。 对象的所谓静态类型,是它在程序中被声明时所采用的类型。你可能会在“调用一个定义于derived class 内的virtual函数”的同时,却使用了ba原创 2014-07-03 16:55:14 · 862 阅读 · 0 评论 -
Effective C++:条款36:绝不重新定义继承而来的non-virtual函数
(一)首先有下面的继承体系:class B { public: void mf(); ... }; class D : public B {...};D x;以下行为:B* pB = &x;pB->mf();异于以下行为:D* pD = &x;pD->mf();上面两种行为产生的结果不一定相同。看下面这种原创 2014-07-03 15:43:10 · 781 阅读 · 0 评论 -
Effective C++:条款18:让接口容易被正确使用,不易被误用
(一)看下面这个例子:class Date { public: Date(int month, int day, int year);};很有可能引起下面这两个错误:(1)他们也许会以错误的次序传递参数,如:Date d(30, 3, 1995); (2)他们可能传递一个无效的月份或天数,如:Date d(2, 30, 1995); 许多像这类客户端错误。原创 2014-06-11 20:27:53 · 813 阅读 · 0 评论 -
Effective C++:条款24:若所有参数皆需类型转换,请为此采用non-member函数
(一)假设一个class用来表现有理数,允许整数“隐式转换为”有理数似乎很合理。class Rational{ public: Rational(int numerator = 0, int denominator = 1); //刻意不为explicit;允许int-to-Rational隐式转换 int numerator()const; int den原创 2014-06-22 21:34:26 · 791 阅读 · 0 评论 -
Effective C++:条款42:了解typename的双重意义
(一)template声明式中,class和typename这两个关键字意义完全相同template class Widget;template class Widget;(二)template void print2nd(const C& container) { if (container.size() >= 2) {原创 2014-09-19 21:38:38 · 606 阅读 · 0 评论 -
Effective C++:条款41:了解隐式接口和编译期多态
(一)首先看下面的类以及函数:class Widget {public: Widget(); virtual ~Widget(); virtual size_t size() const; virtual void normalize(); virtual swap(Widget& other);};void doProcessing(Widget& w) { if(w.原创 2014-09-19 21:22:20 · 741 阅读 · 0 评论 -
ACM:贪心法:乘船问题。
题目:有n个人,第i个人的重量为wi,每艘船的最大载重量均为C,且最多只能乘两个人。用最少的船装载所有人。分析:贪心法! 考虑最轻的人i,他应该和谁一起坐呢?如果每个人都无法和他一起坐船,那么唯一的方案就是每个人坐一艘船! 否则,他应该选择能和他一起坐船的人中最重的一个j。 这样的方法是贪心的!因为:它只是让“眼前”的浪费原创 2014-06-11 21:54:56 · 2878 阅读 · 0 评论 -
Effective C++ 条款 51:编写new和delete时需固守常规
(一)实现一致性operator new必须返回正确的值,内存不足时必须调用new_handling函数,必须有对付零内存的准备,还需要避免不慎掩盖正常形式的new。void* operator new(std::size_t size) throw(std::bad_alloc) { using namespace std; if (size == 0) {原创 2014-09-29 12:00:19 · 633 阅读 · 0 评论 -
Effective C++ 条款 50:了解new和delete的合理替换时机
(一)为什么有人想要替换operator new 和 operator delete呢?三个常见的理由:(1)用来检测运用上的错误。(2)为了强化效果。(3)为了收集使用上的统计数据。(二)下面是个快速发展得出的初阶段global operator new,促进并协助检测“overruns”或“underruns”。static const int原创 2014-09-29 10:35:29 · 827 阅读 · 0 评论 -
Effective C++ 条款 49:了解new-handler的行为
(一)new_handler函数:当operator new或operator new[]分配内存失败时调用的函数。set_new_handler函数:试图分配更多内存以足够使用,成功时会返回,否则会抛出一个bad_alloc异常(或其派生类对象)或调用cstdlib的abort()或exit()函数强制退出。(二)当operator new分配内存失败(不足)时,原创 2014-09-28 21:17:35 · 597 阅读 · 0 评论 -
Effective C++ 条款 48:认识template元编程
(一)template metaprogramming(模板元编程)是编写template-based c++程序并执行于编译期的过程。是以c++写成,执行于c++编译器内的程序。一旦TMP程序执行结束,其输出,也就是template具现出来的若干c++源码,便会一如往常的编译。条款47指出,advance那个typeid-based解法的效率比traits解法低,因为此方案中,1.类原创 2014-09-25 18:27:53 · 666 阅读 · 0 评论 -
Effective C++ 条款 47:使用traits classes表现类型信息
(一)stl主要由“用以表现容器、迭代器和算法”的template构成,但也覆盖若干工具性的templates,其中一个名为advance,将某个迭代器移动某个给定距离:templatevoid advance(IterT& iter, DistT d); //将迭代器向前移动d个单位,d(二)STL里面的迭代器的分类:Input迭代器只能向前移动,一次一步,只读,原创 2014-09-25 14:36:59 · 801 阅读 · 0 评论 -
Effective C++ 条款 46:需要类型转换时请为模板定义非成员函数
(一)首先我们回顾条款24,它说过为什么惟有non-member函数才有能力“在所有实参身上实施隐式类型转换”。现在我们将Rational和operator*模板化:templateclass Rational {public: Rational(const T& number = 0, const T& denominator = 1); const T number() c原创 2014-09-23 22:09:54 · 653 阅读 · 0 评论 -
Effective C++:条款45:运用成员函数模板接受所有兼容类型
(一)所谓智能指针是“行为像指针”的对象,并提供指针没有的机能。真实指针做的很好的一件事是。Derived class指针可以隐式转换为base class指针。指向non-const的对象的指针可以转换为指向const对象。例如:class Top{...}; class Middle: public Top{...}; class Bottom: public Mi原创 2014-09-22 17:53:36 · 652 阅读 · 0 评论 -
Effective C++:条款44:将与参数无关的代码抽离template
(一) template是节省时间和避免重复代码的一个奇妙方法。class template的成员函数只有在被使用时才被暗中具现化。function templates有类似的诉求。 但是如果你不小心,使用templates可能导致代码膨胀(code bloat):其二进制代码带着重复(或几乎重复)的代码、数据、或两者。其结果可能源码看起来合身整齐,但目标码却不是那原创 2014-09-21 11:28:41 · 1017 阅读 · 0 评论 -
Effective C++:条款43:学习处理模板化基类内的名称
(一)注意从 “面向对象的C++” 转向 “模板C++” 时继承可能遭遇问题 :由于基类模板可能被特化,而该特化版本可能会改变成员,因此C++拒绝在模板化基类中寻找继承而来的名称。(二)看下面的例子:假设将信息传送到不同的公司去,传送方式包括明文传送和密文传送,采用模板类的设计方法:class CompanyA {public: ... void sendCl原创 2014-09-20 13:56:57 · 945 阅读 · 0 评论 -
Effective C++:条款28:避免返回 handles 指向对象内部成员
(一)有时候为了让一个对象尽量小,可以把数据放在另外一个辅助的struct中,然后再让一个类去指向它。看下面的代码:class Point {public: Point(int x, int y); void setX(int newVal); void setY(int newVal);};struct RectData { Point ulhc; Point lrhc原创 2014-06-24 09:48:20 · 899 阅读 · 0 评论 -
Effective C++:条款16:成对使用new和delete时要采取相同形式
(一)先看下面的代码:string* stringArray = new std::string[100];...delete stringArray;这样的做法是错误的,因为stringArray所含的100个string对象中的99个可能并没有被适当地删除,因为它们的析构函数很可能没有被调用。 (二)使用new时发生的事情:(1)内存被分配出来;(2)针原创 2014-06-11 16:22:08 · 728 阅读 · 0 评论 -
Effective C++:条款14:在资源管理类中小copying行为
(一)上一条款说的auto_ptr和tr1::share_ptr适合于heap-based的资源,然而并不是所有资源都是heap-based的。换句话说并不是tr1::shared_ptr 和 auto_ptr 永远适合做为资源的管理者。所以有时难免还是需要实现自己的资源管理类型。假设Mutex类型通过lock和unlock两组函数进行互斥器的锁定和解锁,可能我们希望和auto_ptr一样原创 2014-06-11 13:15:39 · 798 阅读 · 0 评论 -
Effective C++:条款10:令operator=返回一个reference to *this。
(一)看下面的连锁赋值式:int x, y, z;x = y = z = 15;在编译器里面实际会被解析为:x = (y = (z = 15));能实现连锁赋值的原因是我们的赋值操作符返回的是一个reference to *this!指向操作符的左侧实参!class Widget {public: ... Widget& operator=(const Wi原创 2014-06-08 12:56:02 · 570 阅读 · 0 评论 -
Effective C++:条款04:确定对象被使用前已先被初始化
(一)读取未初始化的值会导致不明确的行为;array不保证其内容被初始化,但是vector却有此保证;最佳处理办法:永远在使用对象之前先将它初始化;确保每一个构造函数都将对象的每一个成员初始化;(二)利用构造函数成员初值列来初始化对象而不要利用在构造函数体内赋值的方法,原因在代码后面表述:不要用下面这种方法:class PhoneNumber{...};class ABEn原创 2014-06-05 19:27:59 · 583 阅读 · 0 评论 -
Effective C++:条款02:尽量以const,enum,inline替换#define
类似于#define ASPECT_PATIO原创 2014-06-05 12:00:49 · 522 阅读 · 0 评论 -
Effective C++:条款05:了解C++默默编写并调用哪些函数
(一)如果写下:class Empty { };其实就好像我们写了如下代码,但是只有当这些函数被需要(被调用),它们才会被编译器创建出来。class Empty { public: Empty() {...} Empty(const Empty& rhs) {...} ~Empty() {...} //编译器产出的析构函数是个non-virtu原创 2014-06-06 13:36:16 · 556 阅读 · 0 评论 -
Effective C++:条款30:透彻了解inlining的里里外外
(一)inline函数,可以调用它们而又不需蒙受函数调用所招致的额外开销。inline函数背后的整体观念是,将“对此函数的每一个调用”都已函数本体替换之,这样做可能增加你的目标码(object code)大小。在内存有限的机器上,过度inline会造成程序体积太大,导致换页行为,降低缓存的命中率等一些带来效率损失的行为。如果inline函数的本体很小,编译器针对“函数本体”所产生的码可能比原创 2014-06-25 16:40:38 · 824 阅读 · 0 评论 -
Effective C++:条款32:确定你的public继承塑模出is-a关系
(一)public继承意味着“is-a”关系。它的意思是:如果B以public形式继承自A,那么B类型对象肯定是一个A对象,反之不成立。A是B的一种抽象,B是A的特例。任何使用A的地方,都能使用B。(二)public继承意味着“is a”(是一种)关系:(1)任何一个继承类对象也是一个基类对象;(2)任何可以出现基类对象的地方也可以出现一个继承类对象(例如函数的原创 2014-06-26 12:07:25 · 837 阅读 · 0 评论 -
Effective C++:条款31:将文件间的编译依存关系将至最低
(一)假设你对C++程序的某个class实现文件做了些轻微改变,修改的不是接口,而是实现,而且只改private成分。然后重新建置这个程序,并预计只花数秒就好,当按下“Build”或键入make,会大吃一惊,因为你意识到整个世界都被重新编译和链接了!问题是在C++并没有把“将接口从实现中分离”做得很好。避免陷入这种窘境的一种有效的方法就是本条款要提出的内容:将文件间的编译依存关系降至最低.原创 2014-06-25 22:31:42 · 808 阅读 · 0 评论 -
Effective C++:条款26:尽可能延后变量定义式的出现时间
(一)那么当程序的控制流到达这个变量定义时,变承受构造成本;当变量离开作用域时,便承受析构成本。string encryptPassword(const std::string& password) { using namespace std; string encrypted; if(password.length() < MinimumPasswordLengt) { t原创 2014-06-23 15:48:41 · 753 阅读 · 0 评论 -
Effective C++:条款25:考虑写出一个不抛异常的swap函数
(一)缺省情况下swap动作可由标准程序库提供的swap算法完成:namespace std { template void swap(T& a, T& b) { T temp(a); a = b; b = temp; } }这个函数是异常安全性编程的核心,并且是用来处理自我赋值可能性的一个常见机原创 2014-06-23 14:52:12 · 1005 阅读 · 0 评论 -
Effective C++:条款29:为“异常安全”而努力是值得的
(一)先看下面这些代码:class PrettyMenu {public: void changeBackground(istream& imgSrc);private: Mutex mutex; //由于这个class希望用于多线程环境,所以它有这个互斥器作为并发控制之用 Image* bgImage; //目前的背景图像 int imageChan原创 2014-06-24 18:11:04 · 1092 阅读 · 0 评论 -
Effective C++:条款34:区分接口继承和实现继承
(一)class Shape { public: virtual void draw() const = 0; virtual void error(const string& msg); int objectID() const; }; class Rectangle : public Shape {...}; class Ellipse : publi原创 2014-06-28 12:49:37 · 763 阅读 · 0 评论 -
Effective C++:条款09:绝不在构造和析构过程中调用virtual函数
首先在阐述本条款前先表明一个重点:我们不该在构造函数和析构函数期间调用virtual函数!(一)首先有以下继承体系:class Transaction { //所有交易的base classpublic: Transaction(); virtual void logTransaction() const = 0;原创 2014-06-07 22:57:15 · 792 阅读 · 0 评论 -
Effective C++:条款33:避免遮掩继承而来的名称
(一)下面这段代码:int x; void someFunc(){ double x; //local variable std::cin>>x; //read a new value to local x}这个指涉的是local变量x,而不是global变量x,因为内存作用域会的名称遮掩外围作用域的名称。当编译器处于someFunc的作用域内并遭遇原创 2014-06-27 12:30:35 · 879 阅读 · 0 评论