
Effective C++
HccqXd
这个作者很懒,什么都没留下…
展开
-
条款48:认识template元编程——263
文章目录TMP的优缺点——263总结——268template metaprogramming(TMP,模板元编程)是编写template-based C++程序并执行于编译期的过程。TMP的优缺点——263TMP有两个伟大的效力:(1)它让某些事情更容易。(2)由于template metaprograms执行于C++编译期,因此可将工作从运行期转移到编译期。基于第2个效力产生3个结...原创 2019-12-30 13:32:20 · 265 阅读 · 0 评论 -
条款47:请使用traits classes表现类型信息——256
文章目录总结——262我们期望的以下列方式实现advance:template<typename IterT,typename DistT>void advace(IterT& iter,DistT d){ if(iter is a random access iterator) { iter+=d; //针对random acce...原创 2019-12-30 13:31:14 · 205 阅读 · 0 评论 -
条款46:需要类型转换时请为模板定义非成员函数——252
文章目录总结——256将条款24的例子换成模板:template<typename T>class Rational{public: Rational(cosnt T& numerator=0, const T& denominator=1); const T numerator() const; cons...原创 2019-12-30 13:29:59 · 216 阅读 · 0 评论 -
条款45:运用成员函数模板接受所有兼容类型——248
文章目录Template和泛型编程——249总结——252Template和泛型编程——249我们来构造一个成员函数模板:template<typename T>class SmartPtr{public: template<typename U> SmartPtr(const SmartPtr<U>& other); ...原创 2019-12-30 13:29:08 · 172 阅读 · 0 评论 -
条款44:将与参数无关的代码抽离template——242
文章目录去同存异(共性与变形分析)——242总结——247去同存异(共性与变形分析)——242template的确让源代码看起来合身而整齐,但是其目标码却不是那么回事。考虑下面例子:template<typename T,std::size_t n> //template支持nxn矩阵,元素是类型为T的objectclass SquareMatrix{public: ...原创 2019-12-30 13:27:56 · 202 阅读 · 0 评论 -
条款43:学习处理模板化基类内的名称——237
文章目录三个办法令C++“不进入templatized base classes观察”的行为失效——240总结——242当我们从Object Oriented C++跨进Template C++,继承就不像以前那般畅行无阻了。三个办法令C++“不进入templatized base classes观察”的行为失效——240(1)在base class函数调用动作之前加上“this—>”...原创 2019-12-30 13:27:08 · 217 阅读 · 0 评论 -
条款42:了解typename的双重意义——233
文章目录从属类型、嵌套从属类型和非从属类型——234无论何时,请在嵌套从属类型名称前放上关键字typename——234typename 不可出现在base class list内的嵌套从属类型名称之前,也不可在member initializationlist中作为base class 修饰符——236总结——237从属类型、嵌套从属类型和非从属类型——234我们来看下面例子:templa...原创 2019-12-30 13:26:25 · 224 阅读 · 0 评论 -
条款41:了解隐式接口和编译器多态——229
文章目录显示接口和运行期多态——229隐式接口和编译器多态——230总结——233显示接口和运行期多态——229我们来看这样的例子:class Widget{public: Widget(); virtual ~Widget(); virtual std::size_t size() const; virtual void normalize(); ...原创 2019-12-30 13:25:24 · 153 阅读 · 0 评论 -
条款39:明智而审慎地使用private继承——217
文章目录private继承的规则——217private继承意味implemented-in-terms-of——217何时选择private继承——218当protected成员和/或virtual函数牵扯进来的时候考虑选择private继承——218当继承空类使用private继承——220总结——222private继承的规则——217(1)如果class之间的继承关系是private,...原创 2019-12-11 16:27:16 · 343 阅读 · 0 评论 -
条款40:明智而审慎地使用多重继承——222
文章目录多重继承可能会产生歧义——222虚拟继承——223在Interface class中使用多重继承——225总结——228多重继承可能会产生歧义——222比如我们有以下继承体系:class BorrowableItem{public: void checkOut(); ...};class ElectronicGadget{private: bool c...原创 2019-12-11 16:26:02 · 206 阅读 · 0 评论 -
条款38:通过复合塑模出has-a或“根据某物实现出”——214
文章目录总结——216复合(composition)是类型之间的一种关系,当某种类型的对象内含它种类型的对象,便是这种关系。例如:class Address { ... };class PhoneNumber { ... };class Person{public: ...private: std::string name; Address address; ...原创 2019-12-11 16:27:21 · 161 阅读 · 0 评论 -
条款37:绝不重新定义继承而来的缺省参数值——210
文章目录virtual函数是动态绑定,而缺省参数值是静态绑定——201总结——213virtual函数是动态绑定,而缺省参数值是静态绑定——201这节应该好理解。总结——213绝对不要重新定义一个继承而来的缺省参数值,因为缺省参数值都是静态绑定,而virtual函数——你唯一应该复写的东西——却是动态绑定。...原创 2019-11-29 17:29:22 · 153 阅读 · 0 评论 -
条款36:绝不重新定义继承而来的non-virtual函数——208
文章目录非虚拟函数是静态绑定的——208虚拟函数是动态绑定的——209总结——210非虚拟函数是静态绑定的——208结合条款33:如果基类一个非虚拟函数,派生类也有这个函数的定义,派生类中的此函数会遮掩基类的函数。因为非虚拟函数是静态绑定的。讨论以下定义:class B{public: void mf(); ...};class D:public B{ public...原创 2019-11-29 17:28:10 · 208 阅读 · 0 评论 -
条款35:考虑virtual函数以外的其他选择——199
文章目录借由Non-Virtual Interface手法实现Template Method模式——200借由Function Pointer实现Strategy模式——201借由tr1::function完成Strategy模式——203总结——207借由Non-Virtual Interface手法实现Template Method模式——200一个思想流派主张:virtual函数应该几乎...原创 2019-11-29 17:25:53 · 210 阅读 · 0 评论 -
条款34:区分接口继承和实现继承——191
文章目录声明一个纯虚拟函数的目的是为了让派生类只继承函数接口——192声明简朴的impure virtual函数的目的,是让派生类继承该函数的接口和缺省实现——193总结——199我们来使用一个例子来区分接口继承和函数实现继承:class Shape{ //声明一个几何图形的形状类public: virtual void draw() const=0; //于某个隐喻的视...原创 2019-11-29 17:24:59 · 192 阅读 · 0 评论 -
条款33:避免遮掩继承而来的名称——186
文章目录总结——191这个条款主要讲了派生类的成员函数如何掩盖基类的成员函数,同时也介绍了使用using声明和inline转交函数使派生类可以看到基类中被掩盖的函数。总结——191(1)派生类内的名称会遮掩基类内的名称。在public继承下从来没有人希望如此。(2)为了让被遮掩的名称再见天日,可使用using声明式或转交函数。...原创 2019-11-29 17:24:01 · 150 阅读 · 0 评论 -
条款32:确定你的public继承塑模出is-a关系——180
文章目录总结——185这个条款主要介绍了“public”继承意味着is-a。同时列举了两个例子可能不如我们所期望的:企鹅是一种鸟但不会飞;正方形是矩形但不能和矩形一些随意改变长度或者宽度。总结——185“public继承”意味is-a。适用于基类身上的每一件事情一定也适用于派生类身上,因为每一个派生类对象也都是一个基类对象。...原创 2019-11-29 17:23:07 · 176 阅读 · 0 评论 -
条款31:将文件间的编译依存关系降至最低——170
文章目录编译依存的问题——170使用指针指向类——172制作Handles classes的两种办法——174总结——178编译依存的问题——170通常,我们的定义的文件包含很多头文件,这些文件和其含入文件之间形成了一种编译依存关系。如果这些头文件中有任何一个被改变,或这些头文件所依赖的其他头文件有任何改变,那么每一个含入我们定义的文件就得重新编译,任何使用我们定义的文件也必须重新编译。这样的...原创 2019-11-29 17:21:56 · 197 阅读 · 0 评论 -
条款30:透彻了解inlining的里里外外——164
文章目录inline函数的优缺点——164inline函数可被隐喻提出,也可明确提出——165virtual函数拒绝inlining——166编译器有意愿inlining某个函数——166尽量不要对构造函数和析构函数inlining——167总结——169inline函数的优缺点——164优点:(1)调用inline函数不需蒙受函数调用所招致的额外开销。(2)编译器对inline函数有能力...原创 2019-11-29 17:20:02 · 170 阅读 · 0 评论 -
条款29:为“异常安全”而努力是值得的——157
文章目录“异常安全”应该满足两个条件——157解决资源泄漏——158解决数据败坏——158结论——164“异常安全”应该满足两个条件——157我们来定义一个变现夹带背景图案的GUI菜单类:class PrettyMenu{public: ... void chageBackground(std::istream& imgSrc); //改变背景图案 ...原创 2019-11-29 17:19:00 · 156 阅读 · 0 评论 -
条款28:避免返回handles指向对象内部成分——153
文章目录总结——156我们来定义一个矩形类:class Point{ //“点”类public: point(int x,int y); ... void setX(int newVal); void setY(int newVal); ...};struct RectData{ //矩形的结构 Point ulhc; ...原创 2019-11-29 17:17:52 · 270 阅读 · 0 评论 -
条款27:尽量少做转型动作——146
文章目录C++提供四种新式转型——147总结——153C++提供四种新式转型——147这个在<<C++ primer 5th>>比较详细地介绍了,现在重复一遍:(1)const_cast通常被用来将对象的常量性转除。它也是唯一有此能力的C+±style转型操作符。(2)dynamic_cast主要用来执行“安全想下转型”,也就是用来决定某对象是否归属继承体系中的某个...原创 2019-11-29 17:15:33 · 155 阅读 · 0 评论 -
条款26:尽可能延后变量定义式的出现时间——143
文章目录延后变量定义的同时,最好要跳过默认构造函数——145要在循环外定义变量——145总结——146延后变量定义的同时,最好要跳过默认构造函数——145std::string encryptPassword(const std::string& password){ if(password.length() < MinimumPasswordLength){ ...原创 2019-11-29 17:14:36 · 150 阅读 · 0 评论 -
条款25:考虑写出一个不抛出异常的swap函数——136
文章目录pimple手法——136swap特化——138不能偏特化function template——139调用swap可以针对std::swap使用using声明式,然后调用swap不可带任何空间修饰符——140总结——142缺省情况下swap的实现如下:namespace std{ template<typename T> void swap(T& a...原创 2019-11-27 10:24:56 · 184 阅读 · 0 评论 -
条款24:若所有参数皆需类型转换,请为此采用non-member函数——132
文章目录总结——135令class支持隐式类型转换通常是个糟糕的主意只有当参数被列于参数列内,这个参数才是隐式类型转换的合格参与者。下面的非成员函数可以实现混合式算数运算:class Rational{ ... //不包括operator*};const Rational operator*(const Rational& lhs,const Rational&...原创 2019-11-27 10:23:42 · 185 阅读 · 0 评论 -
条款23:宁以non-member、non-friend替换menmber函数——128
文章目录对封装性和包裹弹性的理解——129namespace的使用——130可以将一些便利函数放在多个头文件内但隶属同一个命名空间——131总结——132对封装性和包裹弹性的理解——129越少代码可以看到数据(也就是访问它),越多的数据可被封装,而我们也越能自由地改变对象数据,例如改变成员变量的数量、类型等等。namespace的使用——130在C++,比较自然的做法是让非成员函数和涉及到...原创 2019-11-27 10:22:34 · 299 阅读 · 0 评论 -
条款22:将成员变量声明为private——124
文章目录总结——128这个条款介绍了成员变量声明为private的各种好处,主要思想是客户可以方便地通过成员函数来访问成员变量,程序员也可以很方便对成员变量进行修改,具有很好的安全性。总结——128(1)切记将成员变量声明为private。这可赋予客户访问数据的一致性、可细微划分访问控制、允诺约束条件获得保证,并提供class作者以充分的实现弹性。(2)protected并不比public...原创 2019-11-27 10:21:45 · 186 阅读 · 0 评论 -
条款21:必须返回对象时,别妄想返回其reference——120
文章目录返回reference可能指向一个销毁的local stack对象 ——120返回reference指向一个Heap对象可能程序爱你内存泄漏——122返回reference指向static对象仍不可取——122一个“必须返回新对象”的函数的正确写法总结——124返回reference可能指向一个销毁的local stack对象 ——120考虑下列程序:class Rational{...原创 2019-11-27 10:21:06 · 175 阅读 · 0 评论 -
条款20:宁以pass-by-reference-to-const替换pass-by-value——116
文章目录pass-by-value的问题——116采用pass by reference-to-const方法——117以by reference方式传递参数也可以避免slicing(对象切割)问题——118内置类型不适合采用常量引用传递——119总结——120pass-by-value的问题——116默认情况下C++以by value方式传递对象至函数。但是会调用copy构造函数,产生实参的...原创 2019-11-27 10:20:13 · 278 阅读 · 0 评论 -
条款19:设计class犹如设计type——114
文章目录设计高效的class要面对的问题——114总结——116C++(或者其他OOP语言),当定义一个新class,也就定义了一个新type。设计高效的class要面对的问题——114(1)新type的对象应该如何被创建和销毁?(2)对象的初始化和对象的赋值该有什么样的差别?(3)新type的对象如果被passed by value,意味着什么?(4)什么使新type的“合法值”?...原创 2019-11-27 10:19:06 · 148 阅读 · 0 评论 -
条款18:让接口容易被正确使用,不易被误用——108
文章目录以函数替换对象——108限制类型内什么事可做,什么事不能做——110tr1::shared_ptr支持定制型删除器——111总结——113以函数替换对象——108我们来设计一个用来表现日期的class设计构造函数:class Date{public: Date(int month,int day,int year); ...};上面的设计似乎没问题,但是客户很...原创 2019-11-27 10:18:10 · 221 阅读 · 0 评论 -
条款17:以独立语句将newed对象置于智能指针——105
文章目录总结——107假设我们有个函数用来揭示处理程序的优先权,另一个函数用来在某动态分配所得的Widget上进行某些带有优先权的处理:int priority();void processWidget(std::tr1::shared_ptr<Widget> pw,int priority);我们直接用一条语句调用processWidget函数:processWidget...原创 2019-11-26 15:47:41 · 137 阅读 · 0 评论 -
条款16:成对使用new和delete时要采取相同形式——103
文章目录单个对象和数组调用new和delete不同条款17:以独立语句将newed对象置于智能指针——105总结——107单个对象和数组调用new和delete不同如果你调用new时使用[],你必须在对应调用delete时也是用[]。如果你调用new时没有使用[],那么也不该在对应调用delete时使用[]。条款17:以独立语句将newed对象置于智能指针——105假设我们有个函数用来揭示...原创 2019-11-26 15:45:00 · 153 阅读 · 0 评论 -
条款15:在资源管理类中提供对原始资源的访问——99
文章目录将RAII class对象转换为其所内含的原始资源——100总结——102许多API直接指涉资源,所以有时你只得绕过资源管理对象直接访问原始资源。我们来看看下列代码:std::tr1::shared_ptr<Investment> pInv(createInvestment());int daysHeld(const Investment* pi); //返回投资天数...原创 2019-11-26 15:43:26 · 150 阅读 · 0 评论 -
条款14:在资源管理类中小心copying行为——96
文章目录总结——99并非所有资源都是以堆为基础,对那种资源而言,像auto_ptr和shared_ptr这样的智能指针往往不适合作为资源掌管着。既然如此,有可能偶尔你会发现,你需要建立自己的资源管理类。我们使用C API函数处理类型为Mutex的互斥器对象,共有lock和unlock两函数可用:void lock(Mutex* pm); //锁定pm所指的互斥器void unlock(...原创 2019-11-26 15:37:24 · 155 阅读 · 0 评论 -
条款13:以对象管理资源——92
文章目录RAII守则利用auto_prt(已弃用)以避免f函数潜在的资源泄漏可能性——93auto_ptr不能支持复制行为——94使用shared_ptr自动释放资源——94总结——96我们定一个投资行为的程序库,其中各式各样的投资类型继承自一个root类Investment:class Investment( ... );这个程序库系通过一个工厂函数供应我们某特定的Investment对象:...原创 2019-11-26 15:36:23 · 180 阅读 · 0 评论 -
条款12:复制对象时勿忘其每一个成分——87
文章目录总结——90如果你声明自己的拷贝函数,意思就是告诉编译器你并不喜欢缺省实现中的某些行为。编译器仿佛被冒犯似的,会以一种奇怪的方式回敬:当你的实现代码几乎必然出错时却不告诉你。考虑一个类用来表示顾客,其中手工写出(而非由编译器创建)拷贝函数,使得外界对它们的调用会被记录下来:void logCall(const std::string& funcName);class Cus...原创 2019-11-26 15:32:04 · 163 阅读 · 0 评论 -
条款11:在operator=中处理"自我赋值"——83
文章目录总结——87我们来看看下列代码:class Bitmap { ... };class Widget{ ...private: Bitmap* pb; }; Widget& Widget::operator=(const Widget& rhs){ delete pb; pb=new Bitmap(*rhs.pb); ...原创 2019-11-26 15:30:40 · 167 阅读 · 0 评论 -
条款10:令operator=返回一个reference to *this——82
文章目录总结——83为了实现“连锁赋值”,赋值操作符必须返回一个reference指向操作符的左侧实参。比如:class Widget{public: ... Widget& opereator=(const Widget& rhs){ ... return *this; //返回左侧对象 } ...};...原创 2019-11-26 15:28:47 · 139 阅读 · 0 评论 -
条款09:绝不在构造和析构过程中调用virtual函数——78
文章目录总结——82这个条款是C++与Java或C#不相同的一个地方。首先定义一个交易的基类(Transaction):class Transaction{public: Transaction(); virtual void logTransaction() const=0; //做出一份因类型不同而不同的日志记录(log entry) ...};Tran...原创 2019-11-26 15:27:28 · 138 阅读 · 0 评论