Effective C++ Note
文章平均质量分 55
jonson_zc
相信厚积薄发!
展开
-
重载赋值运算符返回reference to *this(Effective C++_10)
考虑下面的代码:int x, y, z;x = y = z = 15; 赋值工作是自右向左结合的,所以上面的赋值链可以解析成这样:x = (y = (z = 15));为了实现这种“连锁赋值”,赋值操作符必须返回一个指向操作符左边的实参的引用;当你为你的类实现赋值运算符时,你应该遵循这一惯例:class Widget {public: ...Widget& operator=(const原创 2015-08-31 17:12:34 · 488 阅读 · 0 评论 -
确定对象试用前已经初始化(Effective C++_4)
读取未初始化的值会导致不明确的行为。最佳处理办法:永远在使用对象之前将它初始化。区分赋值(assignment)和初始化(initialization)。class Sample{public: Sample(const std::string& name);private: std::string theName; int num;}Sample::Sample(const st转载 2015-09-05 09:47:10 · 302 阅读 · 0 评论 -
将成员变量声明为private和用非成员、非友友提高封装性(Effective C++_22、23))
一、将成员变量声明为private (条款22) ■ 切记将成员变量声明为private.这可赋予客户访问数据的一致性,可细微划分访问控制,允诺约束条件获得保证, 并提供class作者以充分的实现弹性. ■ protected并不比public更具封装性.二、宁以非成员、非友元函数替换成员函数(条款23) (1)之所以这样做,是为了减少能够访问private成员的代码的数量,以此原创 2015-09-08 13:10:06 · 1021 阅读 · 0 评论 -
了解inline函数(Effective_C++(30))
1.类似于C中的#define 在C++中,提供了inline函数来代替C中的宏定义。(通常可以使用const来代替单纯变量的宏定义,它可以提供类型检查。对于形似函数的宏,最好改用inline函数来替换宏定义。) 编译器最优化机制通常被设计用来浓缩那些“不含函数调用“的代码,所以当你inline某个函数时,或许编译器就因此有能力对它执行语境相关最优化。2.效率问题 inline函数同#defi转载 2015-09-08 14:55:14 · 301 阅读 · 0 评论 -
避免遮掩继承而来的名称(Effective C++_33)
一、名字覆盖规则名称的遮掩可以分成变量的遮掩与函数的遮掩两类;查找规则:一般先查找局部作用域,然后再查找外围作用域;对于含有继承关系的类,先查找局部作用域,再查找派生类覆盖的作用域,然后再查找基类覆盖的作用域,如果都没有找到,最后查找全局作用域;二、基类成员函数被覆盖 (1)看一段代码:#include <iostream>using namespace std;class Base{pri原创 2015-09-14 19:25:35 · 443 阅读 · 0 评论 -
绝对不要重新定义继承而来的non-virtual函数(Effective C++_36)
一、对于非虚函数同一个对象调用同一个函数,可能产生了不同的行为class B{public: void mf(){ cout<<"B"<<endl; }};class D:public B{};int main(){ D x; B* pb=&x;//获得一个B类型的指针指向x pb->mf(); D* pD=&x;//获得一个D类型原创 2015-09-15 10:41:41 · 752 阅读 · 0 评论 -
绝不要重新定义继承而来的缺省参数值(Effective C++_37)
一、考虑以下代码 代码来源:http://blog.csdn.net/cadcisdhht/article/details/6233170class A{public: virtual void Fun(int number = 10) { std::cout << "A::Fun with number " << number; }};class B:pub转载 2015-09-15 15:37:47 · 331 阅读 · 0 评论 -
区分接口继承和实现继承(Effective C++_34)
一、所谓接口继承,就是派生类只继承函数的接口,也就是声明;而实现继承,就是派生类同时继承函数的接口和实现。二、虚函数、纯虚函数、非虚函数。(1)虚函数: 虚函数是指一个类中你希望重载的成员函数,当你用一个基类指针或引用指向一个继承类对象的时候,你调用一个虚函数,实际调用的是继承类的版本。——MSDN 虚函数用来表现基类和派生类的成员函数之间的一种关系. 虚函数的定义在基类中进行,在需要定义为转载 2015-09-14 19:40:42 · 426 阅读 · 0 评论 -
了解隐式接口和编译期的多态(Effective C++_41)
注:转自http://www.cnblogs.com/jerry19880126/p/3620004.html仅作学习用途一、隐式接口隐式接口是相对于函数签名所代码的显式接口而言的。当我们看到一个函数签名(即函数声明),比如说: string GetNameByStudentID(int StudentID); 我们就知道这个函数有一个整型的形参,返回值是string。但隐式接口是由有效表达式组成的转载 2015-09-15 17:44:02 · 344 阅读 · 0 评论 -
考虑virtual函数以外的其他选择(Effective C++_35)
一、NVI手法实现模版方法模式(1)NVI手法的基本思想该设计是令客户通过public non-virtual成员函数间接调用private virtual函数,称为non-virtual interface(NVI)手法,它是模板方法设计模式的一个独特表示;相当对virtual函数进行一层的包装,可以称为是virtual函数的外覆器(warpper).注:模板方法设计模式,主要思想是基类提供抽象接原创 2015-09-15 09:22:35 · 380 阅读 · 0 评论 -
若所有参数需类型转换,采用non-member函数(Effective_C++(24))
一、考虑下面问题设计一个class表示有理数,它应该支持隐式类型转换,虽然我们说支持隐式类型转换通常是个不好的主意。这是为了我们设计的类可以和内置类型进行运算。例如和整型:class Rational { pbulic: Rational(int numerator = 0, int denominator = 1); //注意这个构造函数不为explicit int numerator(原创 2015-09-08 13:29:58 · 379 阅读 · 0 评论 -
多用引用,而非传值 (Effective C++_20)
默认情况下, C++ 为函数传入和传出对象是采用传值方式的(这是由 C 语言继承而来的特征)。除非你明确使用其他方法,函数的形式参数总会通过复制实在参数的副本来创建,并且,函数的调用者得到的也是函数返回值得一个副本。这些副本是由对象的拷贝构造函数创建的。这使得“传值”成为一项代价十分昂贵的操作。请观察下边的示例中类的层次结构:class Person {public: Person();转载 2015-08-31 14:53:36 · 336 阅读 · 0 评论 -
在operator=中处理自我赋值(Effective C++_11)
一、我们平时习惯写的赋值操作代码 我们平时可能已经习惯了这样的代码,并且认为是对的:#include<iostream>using namespace std;class Demo{public: Demo& operator=(const Demo& x); Demo(int x=10,int y=15):a(x),b(y){ p=new int; }原创 2015-08-31 21:27:01 · 627 阅读 · 1 评论 -
必须返回对象时,别妄想返回引用(Effective C++_21)
一、何时必须用传值一旦把注意力都转向了对象传值方式隐含的效率问题(参见第 20 条)时,对传值方法采取斩草除根的态度,在追求传递引用方式的纯粹性的同时,也犯下了致命的错误:有时候传递的引用所指向的对象并不存在。class Rational {public: Rational(int numerator = 0, int denominator = 1);// 第 24 条中解释了为什么这里的构原创 2015-08-31 16:11:07 · 359 阅读 · 0 评论 -
复制对象时勿忘其每一个成分(Effective C++_12)
一、对于继承的复制控制 (1)一般不含继承时,常见赋值和复制构造函数如下:class Base{public: Base(int x,int y):a(x),b(y){ } Base(const Base& rhs):a(rhs.a),b(rhs.b){ }//复制构造 Base& operator=(const Base& rhs){ a原创 2015-09-07 17:26:19 · 477 阅读 · 0 评论 -
为多态基类声明一个虚析构函数(Effective C++_7)
一、声明虚析构函数的原因(1)先考虑没有声明虚析构函数的代码:#include <iostream>using namespace std;class Base{public: Base(int x,int y):a(x),b(y){ cout<<"Base Construction"<<endl; } virtual void display()=0;原创 2015-09-07 18:00:11 · 540 阅读 · 1 评论 -
尽可能延后变量定义式的出现时间(Effective_C++(26))
一、定义一个对象,往往意味着必须承担构造成本,离开作用域,必须承担析构成本。即使这个对象没有使用过。二、你可能会认为,不会定义一个不使用的对象。考虑下面的情况下,定义一个对象,执行其他操作,然后使用对象,假如在执行其他操作的时候,出现异常,就导致构造和析构了一个没有使用的对象: std::string encryptPassword(const std::string& password){原创 2015-09-08 13:59:18 · 288 阅读 · 0 评论 -
确定public继承出来的是Is_a关系(Effective C++_32)
(1)谨记:public继承意味着“is_a”的关系,假如class D:public B,那么可以说每一个D的对象同时也是每一个B的对象,但是反之不成立,比如,学生是人,但并非所有人都是学生 (2)public继承主张,能够适用于基类身上的每一件事情也一定适用于派生类身上,因为每一个派生类对象也都是一个基类对象 (3)注意区分is_a,has_a(见条款38),i_implemented-in原创 2015-09-08 17:33:02 · 475 阅读 · 0 评论 -
了解编译器默默生成哪些函数(Effective C++_5)
如果没有定义,编译器会为你产生四个函数:(1) 默认构造函数(2) Copy构造函数:将来源对象的每一个non-static成员变量拷贝至目标对象(3) 赋值构造函数:如果你打算在一个“内含reference成员”的class内支持赋值操作,或者内含const成员,你必须自己定义assignment操作(引用和const的特性所决定);如果某个class的base calss的copy ass原创 2015-09-05 10:01:51 · 336 阅读 · 0 评论 -
若不想使用编译器默认生成的函数,就该拒绝(Effective C++_6)
从条款5,我们知道编译器为我们默认生成copy构造函数、copy assignment函数,且是public、inline; 但是,有时我们不想有赋值,和复制构造产生,那我们应该怎么办?解决知道是:将copy构造函数,赋值操作声明为private;但是,对于成员函数和友元,我们还是可以访问private,所以更安全的做法是将其声明为private,且不去实现它,只有声明,没有定义,代码如下:clas原创 2015-09-05 10:59:46 · 331 阅读 · 0 评论 -
const相关用法(Effective C++_3)
一、构造操作和赋值操作的区别 二、const的用法原创 2015-09-04 20:01:54 · 391 阅读 · 0 评论 -
了解typename的双重意义(Effective C++_42)
注:转自http://blog.chinaunix.net/uid-26548237-id-3871044.html仅作学习用途当我们声明template类型参数,class和typename的意义完全相同。在C++的角度来看,声明template参数时,不论使用关键字class或typename,意义完全相同。template<class T> class Widget; //使用"clas转载 2015-09-15 17:57:14 · 355 阅读 · 0 评论