effective C++ 条款 55:让自己熟悉boost

摘要:高质量,源码开放、平台独立、编译器独立的程序库。 http://boost.org,它和c++标准委员会之间有着独一无二的密切关系,并对委员会深具影响力。它以公开进行的同僚复审(public peer review)为基础接纳程序库。 boost对付的主题非常繁多,包括: 字符串与文本处理, 容器, 函数对象和高级编程, lambda,可以让我们轻松的随时随地创建函... 阅读全文

posted @ 2012-02-20 10:53 lidan 阅读 (297) | 评论 (0) 编辑

effective C++ 条款 54:让自己熟悉包括TR1在内的标准程序库

摘要: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 阅读 (1098) | 评论 (0) 编辑

effective C++ 条款 53:不要轻忽编译器的警告

摘要: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 阅读 (142) | 评论 (0) 编辑

effective C++ 条款 52:写了placement new也要写placement delete

摘要:Widget* pw = new Widget; 共有两个函数被调用:一个分配内存的operator new,一个Widget的default构造函数。 假设第一个调用成功,第二个却抛出异常。步骤一所分配内存必须取消并恢复旧观,否则会造成内存泄漏。这时,客户没能力归还内存,因为Widget构造函数抛出异常,pw尚未被赋值,客户手上也就没有指针指向该被归还的内存。取消步骤一,并恢复旧观... 阅读全文

posted @ 2012-02-19 23:01 lidan 阅读 (980) | 评论 (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 ==... 阅读全文

posted @ 2012-02-19 20:45 lidan 阅读 (305) | 评论 (0) 编辑

effective C++ 条款 50:了解new和delete的合理替换时机

摘要:为什么有人想要替换operator new 和 operator delete呢?三个常见的理由: 1.用来检测运用上的错误。 如果将“new所的内存”delete却不幸失败,会导致内存泄漏。如果在“new所得内存”身上多次delete会导致不确定行为。如果new持有一串动态分配的所得地址,operator delete将地址从中移走,倒是很容易检测出上述错误用法。此外各式各样的编程错误... 阅读全文

posted @ 2012-02-19 10:45 lidan 阅读 (919) | 评论 (0) 编辑

effective C++ 条款 49:了解new-handler的行为

摘要:当operator new无法满足某一内存分配需求时,会抛出异常。再抛出异常以反映一个未获满足的内存需求之前,它会先调用客户指定的错误处理函数,new-handler。为了指定这个“用以处理内存不足”的函数,客户必须调用set-new-handler,那是声明于<new>的一个标准函数库函数: namespace std{ typedef void (*new_handle... 阅读全文

posted @ 2012-02-18 22:27 lidan 阅读 (988) | 评论 (0) 编辑

effective C++ 条款 48:认识template元编程

摘要:template metaprogramming(模板元编程)是编写template-based c++程序并执行于编译期的过程。是以c++写成,执行于c++编译器内的程序。一旦tmp程序执行结束,其输出,也就是template具现出来的若干c++源码,便会一如往常的编译。 tmp有两个伟大的效力。第一,它让某些事情更容易。如果没有它,那些事情将是困难的,甚至是不可能的。第二,由于tmp执... 阅读全文

posted @ 2012-02-17 22:52 lidan 阅读 (210) | 评论 (0) 编辑

effective C++ 条款 47:使用traits classes表现类型信息

摘要: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 阅读 (314) | 评论 (0) 编辑

effective C++ 条款 45:运用成员函数模板接受所有兼容类型

摘要:所谓智能指针是“行为像指针”的对象,并提供指针没有的机能。 真实指针做的很好的一件事是,支持隐式转换。Derived class指针可以隐式转换为base class指针。指向non-const的对象的指针可以转换为指向const对象。下面是发生于三层继承体系的一些转换: class Top{...}; class Middle: public Top{...}; ... 阅读全文

posted @ 2012-02-15 22:41 lidan 阅读 (310) | 评论 (0) 编辑

effective C++ 条款 44:将与参数无关的代码抽离templates

摘要:template是节省时间和避免重复代码的一个奇妙方法。class template的成员函数只有在被使用时才被暗中具现化。function templates有类似的诉求。 但是如果你不小心,使用templates可能导致代码膨胀(code bloat):其二进制代码带着重复(或几乎重复)的代码、数据、或两者。其结果可能源码看起来合身整齐,但目标码却不是那么回事。你需要知道如何避免这样的... 阅读全文

posted @ 2012-02-15 20:50 lidan 阅读 (299) | 评论 (0) 编辑

effective C++ 条款 43:学习处理模板化基类内的名称

摘要:我们需要一个程序,传送信息到不同的公司去。信息要不译成密码,要不就是未加工的文字。如果编译期间我们有足够信息来决定哪一个信息传至那一家公司,就可以采用基于template的解法: class CompanyA{ public: void sendCleartext(const std::string& msg); void sendEncrypt... 阅读全文

posted @ 2012-02-15 15:02 lidan 阅读 (240) | 评论 (0) 编辑

effective C++ 条款 42:了解typename的双重意义

摘要: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 阅读 (546) | 评论 (0) 编辑

effective C++ 条款 41:了解隐式接口和编译期多态

摘要:面向对象编程世界总是以显示接口(explicit interface)和运行期多态(runtime polymorphism)解决问题。 class Widget{ public: Widget(); virtual ~Widget(); virtual std::size_t size() const; vi... 阅读全文

posted @ 2012-02-14 17:27 lidan 阅读 (276) | 评论 (0) 编辑

effective C++ 条款 40:明智而审慎地使用多重继承

摘要:一旦涉及多重继承(multiple inheritance;MI): 程序有可能从一个以上的base class继承相同名称(如函数、typedef等)。那会导致较多的歧义机会。例如: class BorrowableItem { public: void checkOut(); }; class ElectronicGadet { p... 阅读全文

posted @ 2012-02-14 15:53 lidan 阅读 (328) | 评论 (0) 编辑

effective C++ 条款 39:明智而审慎地使用private继承

摘要: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 阅读 (465) | 评论 (0) 编辑

effective C++ 条款 38:通过复合塑模出has-a或“根据某物实现出”

摘要:复合(composition)是类型之间的一种关系,当某种类型的对象内含它种类型的对象,便是这种关系: class Address {...}; class PhoneNumber {...}; class Person { public: ... private: std::string name;//合成成分物 ... 阅读全文

posted @ 2012-02-12 20:36 lidan 阅读 (260) | 评论 (0) 编辑

effective C++ 条款 37:绝不重新定义继承而来的缺省参数值

摘要:重新定义一个继承而来的non-virtual函数永远都是错误的,本条款的讨论限制在“带有缺省参数的virtual函数”。 virtual函数是动态绑定的,而缺省参数却是静态绑定。 对象的所谓静态类型,是它在程序中被声明时所采用的类型。 class Shape { public: enum ShapeColor {Red, Green, Blue}; ... 阅读全文

posted @ 2012-02-11 20:53 lidan 阅读 (358) | 评论 (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(); 你可能相当惊讶。两者的行为确实应该相同,但是如果mf... 阅读全文

posted @ 2012-02-11 17:09 lidan 阅读 (291) | 评论 (0) 编辑

effective C++ 条款 35:考虑virtual函数以外的其他选择

摘要:假设你整在写一个视频游戏软件,由于不同的人物可能以不同的方式计算它们的健康指数,将healthValue声明为virtual似乎再明白不过的做法:class GameCharacter { public: virtual int healthValue()const; ... };由于这个设计如此明显,你可能没有认真考虑其他替代方案。为了帮助你跳脱面向对象设计路上的常轨,让我们考虑其他一些解法:藉由Non-virtual interface手法实现Template Method模式有个思想流派主张virtual函数应该几乎总是private。他们建议,较好的设计是保留healthValue.. 阅读全文

posted @ 2012-02-10 22:32 lidan 阅读 (408) | 评论 (0) 编辑

effective C++ 条款 34:区分接口继承和实现继承

摘要:身为class设计者,有时候你希望derived class只继承成员函数的接口(也就是声明):有时候你又希望derived class同时继承函数的 接口和实现,但又希望能够覆写(override)它们所继承的实现:又有时候你希望derived class同时继承函数的接口与实现,并且不允许覆写任何东西。 让我们考虑一个展现绘图程序中各种几何形状的class继承体系: cla... 阅读全文

posted @ 2012-02-10 14:37 lidan 阅读 (554) | 评论 (0) 编辑

effective C++ 条款 33:避免遮掩继承而来的名称

摘要:这个题材其实和继承无关,而是和作用域(scopes)有关。 int x; void someFunc() { double x; std::cin >> x; } 这个指涉的是local变量x,而不是global变量x,因为内存作用域会的名称遮掩外围作用域的名称。 当编译器处于someFunc的作用域内并遭遇名称x... 阅读全文

posted @ 2012-02-09 21:38 lidan 阅读 (279) | 评论 (0) 编辑

effective C++ 条款 32:确定你的public继承塑模出is-a

摘要:如果你令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 阅读 (242) | 评论 (0) 编辑

effective C++ 条款 31:将文件间的编译依存关系降至最低

摘要:假设你对c++程序的某个class实现文件做了些轻微改变,修改的不是接口,而是实现,而且只改private成分。 然后重新建置这个程序,并预计只花数秒就好,当按下“Build”或键入make,会大吃一惊,因为你意识到整个世界都被重新编译和链接了! 问题是在c++并没有把“将接口从实现中分离”做得很好。class 的定义式不只详细叙述了class接口,还包括十足的实现细目: cl... 阅读全文

posted @ 2012-02-05 22:51 lidan 阅读 (681) | 评论 (0) 编辑

effective C++ 条款 30:透彻了解inlining的里里外外

摘要:inline函数,可以调用它们而又不需蒙受函数调用所招致的额外开销 当你inline某个函数,或许编译器就因此又能力对它(函数本体)执行语境相关最优化。 然而,inline函数背后的整体观念是,将“对此函数的每一个调用”都已函数本体替换之,这样做可能增加你的目标码(object code)大小。在内存有限的机器上,过度inline会造成程序体积太大,导致换页行为,降低缓存的命中率... 阅读全文

posted @ 2012-02-04 23:43 lidan 阅读 (374) | 评论 (0) 编辑

effective C++ 条款 29:为“异常安全”而努力是值得的

摘要:有个class用来表现夹带背景图案的GUI菜单单,这个class用于多线程环境: class PrettyMenu{ public: ... void changeBackground(std::istream& imgSrc); ... private: Mutex mutex; ... 阅读全文

posted @ 2012-02-03 15:20 lidan 阅读 (450) | 评论 (0) 编辑

effective C++ 条款 28:避免返回handles指向对象内部成分

摘要:假设程序涉及矩形。为了让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 阅读 (235) | 评论 (0) 编辑

effective C++ 条款 27:尽量少做转型动作

摘要:转型(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 阅读 (248) | 评论 (0) 编辑

effective C++ 条款 26:尽可能延后变量定义式的出现时间

摘要:只要定义一个变量,而其类型带有一个构造函数或析构函数, 那么当程序的控制流到达这个变量定义时,变承受构造成本;当变量离开作用域时,便承受析构成本。 //这个函数过早定义变量“encrypted” std::string encryptPassword(const std::string& password) { using namespace std; ... 阅读全文

posted @ 2012-01-25 14:33 lidan 阅读 (166) | 评论 (0) 编辑

effective C++ 条款 25:考虑写出一个不抛出异常的swap函数

摘要:缺省情况下swap动作可由标准程序库提供的swap算法完成: namespace std{ template<typename T> void swap(T& a, T& b) { T temp(a); a = b; b = temp; } ... 阅读全文

posted @ 2012-01-20 23:47 lidan 阅读 (967) | 评论 (0) 编辑

effective C++ 条款 24:若所有参数皆需类型转换,请为此采用non-member函数

摘要:令class支持类型隐式转换通常是个糟糕的主意。当然这条规定在建立数值类型时,有例外。假设一个class用来表现有理数,允许整数 “隐式转换为”有理数似乎很合理。 class Rational{ public: Rational(int numerator = 0, int denominator = 1); //刻意不为explicit;允许int-to-... 阅读全文

posted @ 2012-01-20 10:36 lidan 阅读 (249) | 评论 (0) 编辑

effective C++ 条款 23:宁以non-member、non-friend替换member函数

摘要:有个class来表示网页浏览器: class WebBrowser { public: void clearChache(); void clearHistory(); void removeCookies(); protected: private: }; 许多用户会想一整个执行所... 阅读全文

posted @ 2012-01-19 00:10 lidan 阅读 (642) | 评论 (0) 编辑

effective C++ 条款 22:将成员变量声明为private

摘要:为什么不采用public成员变量 首先,语法一致性考虑,客户唯一能访问对象的方法就是通过成员函数,客户不必考虑是否该记住使用小括号()。 其次,使用函数可以让你对成员变量的处理有更精确的控制。如果成员变量是public,每个人都可以读写它,但是如果你也函数 取得或设定其值,你就可以实现“不准访问”、“只读访问”,以及”读写访问”甚至”唯写访问“: class AccessLeve... 阅读全文

posted @ 2012-01-18 10:00 lidan 阅读 (660) | 评论 (0) 编辑

effective C++ 条款 21:必须返回对象时别妄想返回其reference

摘要:考虑有理数的class: class Rational { public: Rational(int numerator = 0, int denominator = 1); protected: private: int n, d; friend Rational operator*(const ... 阅读全文

posted @ 2012-01-17 23:20 lidan 阅读 (367) | 评论 (0) 编辑

effective C++ 条款 20:宁以pass-by-reference-to-const替换pass-by-value

摘要:缺省情况下c++以by value 的方式传递对象(或来自)函数。函数参数是以实参的副本为初值,用函数获得的也是函数返回值的一个副本 这些副本由对象的copy构造函数产出,这可能使得pass-by-value成为昂贵的操作: class Person { public: Person(); virtual ~Person(); ... 阅读全文

posted @ 2012-01-17 16:04 lidan 阅读 (326) | 评论 (0) 编辑

effective C++ 条款 19:设计class犹如设计type

摘要:设计优秀的classes和是一项艰巨的工作,因为设计好的types是一项艰巨的工作。设计出至少像c++内置类型一样好的classes。 几乎每一个class都要求面对以下提问,回答往往导致你的设计规范: 1,新type的对象应该如何创建和销毁? 包括构造和析构函数,内存分配和释放函数(operator new, operator delete,operator new[], o... 阅读全文

posted @ 2012-01-17 14:34 lidan 阅读 (238) | 评论 (0) 编辑

effective C++ 条款 18:让接口容易被正确使用,不易被误用

摘要:如果客户企图使用某个接口而却没有获得他所预期的行为,这个代码就不该通过编译,如果代码通过了编译, 它的作为就该是客户所想要的。 class Date { public: Date(int month, int day, int year); ... }; 第一,以错误的次序传递参数: Date(3... 阅读全文

posted @ 2012-01-16 22:32 lidan 阅读 (199) | 评论 (0) 编辑

effective C++ 条款 17:以独立语句将newed对象置入智能指针

摘要:假设一个函数用来揭示处理程序的优先权 int priority(); 另一个函数用来在动态分配的Widget上进行某些带有优先权的处理: void processWidget(std::tr1::shared_ptr<Widget> pw, int priority); 考虑调用processWidget: processWidget(new Widget, pri... 阅读全文

posted @ 2012-01-16 13:56 lidan 阅读 (166) | 评论 (0) 编辑

effective C++ 条款 16:成对使用new和delete时要采用相同形式

摘要:当你使用new,有两件事情发生。 第一,内存被分配出来(通过名为operator new的函数)。 第二,针对此内存会有一个(或多个)构造函数被调用。当你使用delete,也有两件事情发生:针对此内存会有一个或多个析构函数被调用,然后内存被释放。 数组所用的内存通常还包括”数组大小”的记录,以便delete知道调用多少次析构函数。 当你调用new时使用[],你必须在对应... 阅读全文

posted @ 2012-01-15 16:43 lidan 阅读 (123) | 评论 (0) 编辑

effective C++ 条款 15:在资源管理类中提供对原始资源的访问

摘要:资源管理类避免直接处理资源,但是许多APIs直接涉及资源,所以应该提供返回原始资源的函数。 tr1::shared_ptr和auto_ptr都提供一个get成员函数,用来执行显式转换,返回智能指针内部的原始指针(的复件)。 std::tr1::shared_ptr<Investment> pInv(createInvestment()); int daysHeld(const ... 阅读全文

posted @ 2012-01-14 22:49 lidan 阅读 (168) | 评论 (0) 编辑

effective C++ 条款 14:资源管理类中小心copying行为

摘要:并非所有的资源都是heap-based,对那种资源来讲,auto_ptr和shared_ptr这样的智能指针往往不适合作为资源掌管着。你可能需要 自己建立自己的资源管理类。 例如,处理类型为Mutex的互斥器对象,有lock和unlock两函数可用。 void lock(Mutex* pm); void unlock(Mutex* pm); class Loc... 阅读全文

posted @ 2012-01-14 21:22 lidan 阅读 (214) | 评论 (0) 编辑

effective C++ 条款 13:以对象管理资源

摘要:资源是,一旦用了,将来必须还给系统,除了内存常见的还有文件描述符(file description)、互斥锁、图形界面中的笔刷、数据库连接 以及网络socket。考虑到异常、函数内多重回传路径、程序维护员软件改动却没有理解随之而来的冲击,发现资源管理的特殊手段还不很充分够用。 假设一个各式各样的投资类型继承的一个root class Investment: class Inve... 阅读全文

posted @ 2012-01-14 10:56 lidan 阅读 (178) | 评论 (0) 编辑

effective C++ 条款 12:复制对象时勿忘其每一个成分

摘要:copy构造函数和copy assignment操作符,我们称他们为copying函数。这些“编译器生成版”的行为:将被烤对象的所有成员变量 都做一份拷贝。 声明自己的copying函数, void logCall(const std::string funcName); class Customer { public: Custo... 阅读全文

posted @ 2012-01-13 22:49 lidan 阅读 (140) | 评论 (0) 编辑

effective C++ 条款 11:在operator= 处理‘自我赋值’

摘要:假设建立一个class来保存一个指针指向一块儿动态分配的位图(bitmap) class Bitmap{...}; class Widget { public: protected: private: Bitmap* pb; }; 这个operator=实现代码表面看上来合理, 但自我赋值出现时并不安全,也不... 阅读全文

posted @ 2012-01-13 21:34 lidan 阅读 (146) | 评论 (0) 编辑

effective C++ 条款 10:operator= 返回一个reference to *this

摘要:赋值的连锁式 x=y=z=3;被解析成x=(y=(z=3));为了实现“连锁赋值”,赋值操作符必须返回一个reference指向操作符的左侧实参, 这是你为class实现赋值操作符时应该遵循的协议: class Widget { public: Widget& operator=(const Widget& rhs) //返回类型是referenc... 阅读全文

posted @ 2012-01-13 16:46 lidan 阅读 (126) | 评论 (0) 编辑

effective C++ 条款 9:绝不在析构和构造函数中调用virtual函数

摘要:每当创建一个交易对象,在审计日志中也要创建一笔适当记录。下面是一个看起来比较合理的做法: class Transaction { public: Transaction() { init(); } virtual void logTransaction() const { std::cout << "tran... 阅读全文

posted @ 2012-01-13 15:53 lidan 阅读 (393) | 评论 (0) 编辑

effective C++ 条款 8:别让异常逃离析构函数

摘要:c++并不禁止析构函数抛出异常,但它不鼓励这样做: class Widget{ public: … ~Widget(); //假设可能抛出异常 }; void doSomething() { std::vector<Widget> v; … } 当vector v被销毁,它有责任销毁其内含的所有W... 阅读全文

posted @ 2012-01-13 10:29 lidan 阅读 (499) | 评论 (1) 编辑

effective C++ 条款 7:为多态声明virtual析构函数

摘要:c++明确指出,当derived class对象由一个base class指针删除,而该base class带着一个non-virtual析构函数,其结果未有定义— 实际执行时,通常发生的是对象的derived成分没被销毁。会造成“局部销毁”对象。 而避免这个问题很简单:给base class一个virtual析构函数。 任何class只要带有virtual函数,都几乎确定应该有一个v... 阅读全文

posted @ 2012-01-12 19:27 lidan 阅读 (172) | 评论 (0) 编辑

effective C++ 条款 6:若不想使用编译器自动生成的函数,就该明确将拒绝

摘要:为了驳回编译器自动提供的功能, 可将相应的成员函数声明为private并不予实现。如果在成员函数或friend函数调用这些, 连接时会报错。将连接错误移至编译期是可能的,设置一个专门为了防止copying动作的base classs:class Uncopyable{protected: //允许derived对象构造和析构 Uncopyable(){} ~Uncopyable(){}private: //阻止copying Uncopyble(const Uncopyable&); Uncopyable& operator=(const Uncopyable&);}; 阅读全文

posted @ 2012-01-07 23:09 lidan 阅读 (161) | 评论 (0) 编辑

effective C++ 条款 5:了解c++默认编写并调用那些函数

摘要:编译给会为一个空类声明一个default构造函数、一个copy构造函数、一个copy assignment操作符、和一个析构函数。所有这些都是public且inline: class Empty{}; 就像是写了这样的代码: class Empty{ Empty(){…} Empty(const Empty& rhs) {…} ~E... 阅读全文

posted @ 2012-01-07 15:36 lidan 阅读 (178) | 评论 (0) 编辑

effective C++ 条款 4:确定对象被使用前已先被初始化

摘要:对象的成员变量的初始化动作发生在进入构造函数本体之前。ABEntry::ABEntry(const std::string& name, const std::list<PhoneNumber>& phones){ theName = name; //这些都是赋值,不是初始化 thePhones = phones; numTimesConsulted = 0;}这个构造函数首先调用default构造函数为theName, thePhones设初值,然后立刻对他们赋予新值ABEntry::ABEntry(const std::string& name, con 阅读全文

posted @ 2012-01-07 10:16 lidan 阅读 (313) | 评论 (0) 编辑

effective C++ 条款 3:尽可能使用const

摘要:const 修饰指针:如果关键字const出现在星号*左边,表示被指物是常量,如果const出现在*右边表示指针自身是常量, 如果出现在两边表示被指物和指针都是常量; const std::vector<int>::iterator iter = vec.begin(); //iter的作用就像是T* const; ++iter;错误 std::vector<int>::const_iterator cIter = vec.begin(); //cIter的作用像个const T*; *cIter = 10;错误 const 修饰函数返回值:将operator*的返回值 阅读全文

posted @ 2012-01-05 23:11 lidan 阅读 (151) | 评论 (0) 编辑

effective C++ 条款 2:尽量用const和inline而不用#define

摘要:effective C++ 条款 2:尽量用const和inline而不用#define尽量用编译器而不用预处理#define ASPECT_RATIO 1.653 它会被预处理程序去掉,于是ASPECT_RATIO不会加入到符号列表中定义指针常量时会有点不同 要写两次const:const char * const authorName = "Scott Meyers";最好用const std::string authorName("Scott Meyers");另外,定义某个类(class)的常量一般也很方便 而define没有作用域。要把常量限制 阅读全文

posted @ 2011-10-10 00:45 lidan 阅读 (279) | 评论 (0) 编辑

虚拟基类的初始化

摘要:无论虚拟基类出现在继承层次中的哪个位置上,它们都是在非虚拟基类之前被构造虚拟基类的初始化成了最末层继承类的责namespace Ex18_15{ class Base { public: Base(){cout << "Base()\n";}; Base( string ){ cout << "Base(string)\n"; }; Base( const Base&){ cout << "Base(const Base&)\n"; }; // ... protected: stri 阅读全文

posted @ 2011-08-29 11:56 lidan 阅读 (108) | 评论 (0) 编辑

多继承下成员访问

摘要:编译器先解析出他对某个名称该使用哪个实例, 然后再检查实例的访问权限是否合法#include <complex>class Base1 { public: // ... protected: int ival; double dval; char cval; // ... private: int *id; // ... };class Base2 { public: // ... protected: float fval; // ... private: double dval; // ... };class Derived : public Base1 { pub... 阅读全文

posted @ 2011-08-25 09:52 lidan 阅读 (106) | 评论 (0) 编辑

C++中析构函数为什么要是虚函数

摘要:Example 1 // #include <iostream.h> class CFunction { public: CFunction() { data = new char[64]; }; ~CFunction() { delete [] data; }; char *data; }; class CFunctionEx : public CFunction { 阅读全文

posted @ 2011-08-17 22:50 lidan 阅读 (1892) | 评论 (0) 编辑

c++类中成员的构造顺序

摘要:先是父类各成员的初始化, 各成员的默认构造函数, 再调用父类的构造函数,然后是各成员的初始化, 各成员的默认构造函数,然后是自己的构造函数。class a{public: a() { cout << "construct a" << endl; }};class combinebase{public: combinebase() { cout << "construct combinebase" << endl; }};class combine: public combinebase{public: co 阅读全文

posted @ 2011-08-11 11:36 lidan 阅读 (196) | 评论 (0) 编辑

C++中构造函数调用构造函数

摘要:最近在整理C++知识的时候,突然想到如何在C++中实现构造函数调用构造函数的问题,常见的错误是按照如下方式来调用: 1: #include 3: class Test 4: { 5: public: 6: int m_a; 8: Test(int a) 9: {10: m_a = a;11: }13: Test()14: {15: Test(1);16: }17: };19: int main(int argc,char* argv[])20: {21: Test... 阅读全文

posted @ 2011-08-10 23:24 lidan 阅读 (2873) | 评论 (0) 编辑

类模板中的友元声明

摘要:有三种友元声明可以出现在类模板中:1 非模板友元类或友元函数函数 foo() 成员函数bar()以及 foobar类都是类模板QueueItem的所有实例的友元class Foo { void bar(); }; template <class T> class QueueItem { friend class foobar; friend void foo(); friend void Foo::bar(); // ... };2 绑定的 bound 友元类模板或函数模板:在类模板 QueueItem的实例和它的友元也是模板实例之间定义了一对一的映射,对 QueueItem的每一 阅读全文

posted @ 2011-08-04 22:32 lidan 阅读 (1406) | 评论 (0) 编辑

类模板中非类型参数的模板实参

摘要:1,绑定给非类型参数的表达式必须是一个常量表达式,即,它必须能在编译时被计算出结果。2,非 const 对象的值不是一个常量表达式,它不能被用作非类型模板参数的实参3,名字空间域中任何对象的地址,即使该对象不是const 类型,是一个常量表达式,而局部对象的地址则不是。4, sizeof表达式的结果是一个常量表达式,所以它可以被用作非类型模板参数的实参。对于一个模板非类型参数,如果两个不同的表达式的求值结果相同,则它们被认为是等价的模板实参。在模板实参的类型和非类型模板参数的类型之间允许进行一些转换,能被允许的转换集是函数实参上被允许的转换的子集:1 左值转换:包括从左值到右值的转换,从数组到 阅读全文

posted @ 2011-08-04 21:56 lidan 阅读 (494) | 评论 (0) 编辑

操作符重载

摘要:操作符->class ScreenPtr { // ... private:Screen *ptr; };// 支持指针行为的重载操作符 class ScreenPtr { public: Screen& operator*() { return *ptr; } Screen* operator->() { return ptr; } //.... };ps->move( 2, 3 ); 因为成员访问操作符箭头的左操作数的类型是 ScreenPtr 所以使用该类的重载操作符该操作符。返回一个指向 Screen类对象的指针,内置成员访问操作符箭头被依次应用在这个返回值上 阅读全文

posted @ 2011-08-03 22:47 lidan 阅读 (94) | 评论 (0) 编辑

成员初始化表

摘要:使用初始化表和在构造函数内使用数据成员的赋值之间有什么区别:inline Account:: Account( const char *name, double opening_bal ) : _name( name ), _balance( opening_bal ) { _acct_nmbr = get_unique_acct_nmbr(); }inline Account:: Account( const char *name, double opening_bal ) { _name = name; _balance = opening_bal; _acct_nmbr = get_un 阅读全文

posted @ 2011-08-02 22:47 lidan 阅读 (211) | 评论 (0) 编辑

explicit 构造函数的意义

摘要:在类的构造函数中, 凡是只带有一个参数的构造函数, 都定义了一组隐式转换, 把构造函数的参数类型转换成该类的类型;如:Smallint(int)把int型的值转化成Smallint值;extern void cacl(Smallint);int i;//需要把i转换成Smallint值, Smallint(int)能做到这一点calc(i); 可以理解成://创建一个临时对象{Smallint temp = Smallint(i);calc(temp);}如果需要,编译器会在调用构造函数的转换之前,在参数上应用标准转换序列;如:extern void calc(Smallint);double 阅读全文

posted @ 2011-08-02 20:10 lidan 阅读 (232) | 评论 (0) 编辑

程序段的Class Scope

摘要:如果class member的定义在class body之外, 那么从该定义的member名称开始出现到定义结束为止,都属于class scope,但是前边的返回类型不属于class scope。如:typedef int Type;Type initVal();class Exercise{public: typedef double Type; Type setVal(Type); Type initVal(){return 0;};private: int val;};Type/*此处的Type为全局里面定义的int*/ Exercise::setVal(Type parm) //err 阅读全文

posted @ 2011-07-31 17:37 lidan 阅读 (155) | 评论 (0) 编辑

键盘输入EOF,在istream_iterator中, 不输入EOF死循环

摘要:windows中是ctrl+z但是我在vc6下不好使, 有时候要要好几下,有时候ctrl+z后要回车,可以用ctrl+a,也可以用ctrl+d;linux下是ctrl+d istream_iterator<int> iput(cin), eos; ofstream efile("evenfile"); ostream_iterator<int> evenfile(efile, "\n"); ofstream ofile("oddfile"); ostream_iterator<int> oddfil 阅读全文

posted @ 2011-07-30 19:16 lidan 阅读 (475) | 评论 (0) 编辑

需要指定模板函数参数的两种必要情况

摘要:1.当参数推演失败, 产生ambiguous,可以明白指定参数min5<double>(dobj, fobj);2.当编译器无法推演出返回类型时template <class T1, class T2, class T3>T1 sum(T2, T3);指定参数时, 只有尾部的参数可以不写如:sum<double>(fobj, dobj);//返回值类型T1是double, T2是float, T3是doublesum<double, ,double>(fobj, dobj);//错误, 只能省略后面的 阅读全文

posted @ 2011-07-30 15:48 lidan 阅读 (85) | 评论 (0) 编辑

函数对象

摘要:函数对象的实现简单形式包括一个被重载的函数调用操作符, 如下:还可以加入模板, 或者加入构造函数, 添加私有成员等class Lessthan{public:bool operator()(int a, int b){return a < b;}}典型情况下,函数对象被当做实参传递给算法, 也可以独立的定义函数对象。stable_sort(sentences.begin(), sentences.end(), LessThan());Lessthan lt;bool b = lt(3, 5); 阅读全文

posted @ 2011-07-30 12:49 lidan 阅读 (63) | 评论 (0) 编辑

忘记using namespace std;

摘要:在写程序时 经常莫名其妙的出现一些 未定义错误,如下面, 是因为用了c++的名字空间std中的类型;忘了加上using namespace std;语句error C2143: syntax error : missing '; ' before ' < ' error C2143: syntax error : missing '; ' before ' < ' error C2061: syntax error : identifier 'vector ' error C2061: syntax e 阅读全文

posted @ 2011-07-30 11:22 lidan 阅读 (114) | 评论 (0) 编辑

运算符优先级

摘要:醋坛酸味灌,味落跳福逗醋, 初等:4个,(), [], ->, .;坛, 单目, 9个, !, ~, ++, --, -(负号), +, *, &, sizeof酸, 算术, 5个, *, /, %, +, -味, 位移, 2个, <<, >>灌, 关系, 6个, <, >, <=, >=, ==, !=味, 位运算, 3个,&, |, ^(按位异或)落, 逻辑, 2个, &&, ||跳, 条件, 1个, ?:(三目, 自右向左)福, 赋值, 11个,=, +=, -=, *=, /=, %=, >&g 阅读全文

posted @ 2011-07-24 16:42 lidan 阅读 (65) | 评论 (0) 编辑

stdafx.h

摘要:简介 名称的英文全称为:Standard Application Framework Extensions 所谓头文件预编译,就是把一个工程(Project)中使用的一些MFC标准头文件(如Windows.H、Afxwin.H)预先编译,以后该工程编译时,不再编译这部分头文件,仅仅使用预编译的结果。这样可以加快编译速度,节省时间。 预编译头文件通过编译stdafx.cpp生成,以工程名命名,由于预编译的头文件的后缀是“pch”,所以编译结果文件是projectname.pch。 编译器通过一个头文件stdafx.h来使用预编译头文件。stdafx.h这个头文件名是可以在projec... 阅读全文

posted @ 2011-07-24 11:52 lidan 阅读 (525) | 评论 (0) 编辑

VC++ warning C4786 详解

摘要:在使用std::list的过程中, 编译器报warning 如下:warning C4786: 'std::reverse_bidirectional_iterator<std::list<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > 阅读全文

posted @ 2011-07-24 11:18 lidan 阅读 (5288) | 评论 (0) 编辑

带缺省参数的重复声明

摘要:char *screenInit(int height, int width, char background = ' ');char *screenInit(int height = 4, int width = 4, char background);正确;char *screenInit(int height, int width, char background = ' ');char *screenInit(int height = 4, int width = 4, char background = ' ');//redefinit 阅读全文

posted @ 2011-07-23 22:23 lidan 阅读 (114) | 评论 (0) 编辑

effective C++ 第三版相关推荐

  1. Effective Java第三版有哪些新功能?

    自从听说即将出版的有效Java 第三版以来,我一直想知道其中有什么新内容. 我假设将涵盖自Java 6以来引入Java的功能,的确如此. 但是,第三版Java开发人员经典版也有一些其他更改. 在本文中 ...

  2. Java之父James Gosling鼎力推荐《Effective Java 第三版》最新中文版,Java程序员必看神书

    前言 Java之父James Gosling鼎力推荐.Jolt获奖作品全新升级,针对Java 7.8.9全面更新,Java程序员必备参考书.包含大量完整的示例代码和透彻的技术分析,通过90条经验法则, ...

  3. Effective Java 第三版读书笔记(类和接口)

    第15条.使类和成员的可访问性最小化 对于成员有四种可访问级别: 1.私有的(private)----- 只有在声明该成员的顶层类内部才可以访问这个成员. 2.包级私有的(package-privat ...

  4. 有效期判断功能 java_有效的Java第三版有哪些新功能?

    有效期判断功能 java 自从听说即将出版的有效Java 第三版以来,我一直想知道其中有什么新内容. 我假设将涵盖自Java 6以来引入Java的功能,的确如此. 但是,第三版Java开发人员经典版也 ...

  5. 有效的Java第三版有哪些新功能?

    自从听说即将出版的有效Java 第三版以来,我一直想知道其中有什么新内容. 我假设将涵盖自Java 6以来引入Java的功能,的确如此. 但是,第三版Java开发人员经典版也有一些其他更改. 在本文中 ...

  6. LeetCode 342. 4的幂 附带《Effective C++》pdf版下载

    题目描述 给出 N 名运动员的成绩,找出他们的相对名次并授予前三名对应的奖牌.前三名运动员将会被分别授予 "金牌","银牌" 和" 铜牌"( ...

  7. Effective Java(第三版) 学习笔记 - 第四章 类和接口 Rule20~Rule25

    Effective Java(第三版) 学习笔记 - 第四章 类和接口 Rule20~Rule25 目录 Rule20 接口优于抽象类 Rule21 为后代设计接口 Rule22 接口只用于定义类型 ...

  8. Effective C++ 中文版(第三版)读书笔记 更新ing~

    Effective C++ 中文版(第三版)持续更新ing 让自己习惯C++ 条款1 视c++为一个联邦 条款2 尽量以const,enum,inline替换#define 条款3 尽可能使用cons ...

  9. Effective C++中文版第三版 高清完整版PDF

    有人说C++程序员可以分成两类,读过Effective C++的和没读过的.世界顶级C++大师Scott Meyers成名之作的第三版的确当得起这样的评价.当您读过这本书之后,就获得了迅速提升自己C+ ...

最新文章

  1. 《创业维艰分享之五》所有得,有所乐,日事日清,循序渐进。
  2. log算子dog算子
  3. 3.1.10 OS之基本分段存储管理(段表、地址变换、信息共享)
  4. [mybatis]映射文件_select_resultMap_关联查询
  5. 快捷键关机电脑_技巧 | 如何知道电脑多久没关机?一个命令就行嘞!
  6. 49-Python 安装pythoncom库和pyHook
  7. _过程_函数_触发器_游标
  8. 日前加拿大平板厂商 Datawind和印度运营商Reliance Communications日前宣布合作
  9. 8、二叉树的下一个节点(Python)
  10. 面试题之cookie和session区别
  11. C++的iostream标准库介绍+使用详解
  12. C#显示和隐藏 Excel 工作表及工作表中的行与列
  13. Python 新手刚学链表,做了一个“捣浆糊”版的单链表类
  14. centos7挂载nas存储_CentOS 7配置NAS(网络共享存储)
  15. Java设计模式学习笔记
  16. 如何将Excel表格中的数据粘贴到记事本中,且每列间距都为一个空格?
  17. C语言-单词长度统计
  18. android手机如何查找文件在哪里设置,oppoReno怎么快速查找文件/程序/系统设置?
  19. 谷歌开发者大会焦点:TensorFlow.js可制作微信小程序,Android 10原生支持5G,TF2.0大更新...
  20. PL_SQL模块学习之十五、异常

热门文章

  1. 浙大MBA经验分享:在工作生活的缝隙中奋勇上岸
  2. Java学习12.6
  3. 数据库产品-易用性问题
  4. 华工计算机组成原理试卷,华工 2014计算机组成原理 作业答案
  5. 关于GPS模块的一些注意点,包括区分天线。
  6. php callable closure,详解php 使用Callable Closure强制指定回调类型
  7. 那些指责集度ROBO-01抄袭者,更应该学习它对未来汽车的思考
  8. 喜报 | 炼石入选北京市“专精特新”企业
  9. LoadRunner性能测试结果分析样例
  10. 第四章:商品治理五大策略