随笔分类 -  书籍Effective C++

摘要:const成员函数意味着什么呢?一种观点认为意味着bitwise constness(又称physical constness),即const成员函数不能改变对象的任何数据成员(static除外)。作者给出了一个例子反驳了这种观点——一个const成员函数实现时没有改变任何对象的数据成员,看起来像是bitwise constness,但是当它返回指针时,可以利用指针改变对象的数据成员。 另一种观点... 阅读全文
posted @ 2014-03-22 12:59 helloweworld 阅读(180) 评论(0) 推荐(0) 编辑
摘要:条款1:尽量用const和inline而不用#define 本质是你想编译时就检查出错误,还是运行时出错。 const inline是编译期执行,有参数检查等动作,而#define是预编译时执行。 但是不能完全抛弃#define,它可以控制是否编译某段代码。 条款2:尽量用<iostream>而不用<stdio.h> 为什么呢,一个简单的原因是stdio的控制格式实在够烦人的,还有什么原因呢? 作... 阅读全文
posted @ 2013-06-13 13:52 helloweworld 阅读(194) 评论(0) 推荐(0) 编辑
摘要:本条款解决了我的一个疑问,为什么成员初始化顺序和声明的顺序相同,而和初始化列表中的顺序没关系呢? “我们知道,对一个对象的所有成员来说,它们的析构函数被调用的顺序总是和它们在构造函数里被创建的顺序相反。那么,如果允许上面的情况(即,成员按它们在初始化列表上出现的顺序被初始化)发生,编译器就要为每一个对象跟踪其成员初始化的顺序,以保证它们的析构函数以正确的顺序被调用。这会带来昂贵的开销。所以,为... 阅读全文
posted @ 2013-06-06 16:27 helloweworld 阅读(134) 评论(0) 推荐(1) 编辑
摘要:本条款实际上在解决一个疑问,为什么要有成员初始化列表这个东西,直接在构造函数里赋值不行吗? 条款给出了2点理由: 1.有些情况下必须用初始化——特别是const和引用数据成员只能用初始化,不能被赋值。 2.成员初始化列表的效率比赋值的效率高。 看第一种情况: class A{ const int constVal;public:// A() { constVal = 0;} //error ... 阅读全文
posted @ 2013-06-06 16:12 helloweworld 阅读(251) 评论(0) 推荐(0) 编辑
摘要:这个条款在More Effective C++里有进一步的说明,推迟变量的定义被叫做“缓式评估”。 产生本条款做法的根本原因是构造和析构函数有开销。 文中给出了一个例子,如下: // 此函数太早定义了变量"encrypted"string encryptPassword(const string& password){ string encrypted; if (password.lengt... 阅读全文
posted @ 2013-06-03 19:47 helloweworld 阅读(192) 评论(0) 推荐(0) 编辑
摘要:千万不要返回局部对象的引用——局部对象在函数调用完成后被销毁了,若返回其引用,引用的对象都没有了,引用就没意义了。 不要返回函数内部用new初始化的指针的引用——即在一个函数中用new申请一片内存,然后返回指向这片内存的指针,语法和编译上都没错误,但给使用设下了陷阱,因为调用者很可能忘了用delete释放内存,造成内存泄露。 阅读全文
posted @ 2013-06-03 19:38 helloweworld 阅读(255) 评论(0) 推荐(0) 编辑
摘要:类默认生成的函数(当你自己不定义这些函数时): 一个拷贝构造函数,一个赋值运算符,一个析构函数,一对取址运算符、一个缺省构造函数。 class Empty {public: Empty(); // 缺省构造函数 Empty(const Empty& rhs); // 拷贝构造函数 ~Empty(); // 析构函数 ---- 是否 // 为虚函数看下文说明 Empty& operator=(c... 阅读全文
posted @ 2013-05-30 12:09 helloweworld 阅读(132) 评论(0) 推荐(0) 编辑
摘要:这里向下转换指的是“将基类指针强制转换为派生类”,不建议这么做,为什么?根本在访问权限,即派生类对象可以做的事,基类对象不一定能做,如果把基类指针强制转换为派生类,那么基类就可以做派生类独有的事情了。 阅读全文
posted @ 2013-05-29 22:46 helloweworld 阅读(140) 评论(0) 推荐(0) 编辑
摘要:文中给出解释“如果缺省参数值被动态绑定,编译器就必须想办法为虚函数在运行时确定合适的缺省值,这将比现在采用的在编译阶段确定缺省值的机制更慢更复杂。做出这种选择是想求得速度上的提高和实现上的简便”。 缺省参数在编译时绑定,而不是在运行时绑定,主要是为了高效运行。 阅读全文
posted @ 2013-05-29 22:22 helloweworld 阅读(157) 评论(0) 推荐(0) 编辑
摘要:该条款最终结论:任何条件下都要禁止重新定义继承而来的非虚函数。 或者说,应该避免“隐藏”现象的发生(所谓隐藏,即派生类重新定义基类的非虚函数)。另一个概念“覆盖”即对虚函数的重新实现的发生是正常的。 从继承和实现的角度看,虚函数是一个接口,实现可以不同,或者说特性可以不同。但是非虚函数表示一种固有的不变的特性,所以不要改变这个不变的特性,否则违背公有继承“是一个”的原则。 class A{pu... 阅读全文
posted @ 2013-05-28 12:08 helloweworld 阅读(368) 评论(0) 推荐(0) 编辑
摘要:注:下面所说虚函数指不是纯虚函数的普通虚函数。 这里所说的接口继承,指的是继承基类的纯虚函数;实现继承指的是继承基类的虚函数或者普通函数。 本条款实际上讲的是使用纯虚函数还是虚函数的问题。 这个条款概括起来就是: 如果基类不需要实现,实现在派生类中,那么基类中定义纯虚函数; 如果基类有默认实现,某些派生类可能会重新定义实现,那么基类中定义虚函数; 如果派生类完全继承基类的实现,不需任何改变,那... 阅读全文
posted @ 2013-05-28 11:28 helloweworld 阅读(149) 评论(0) 推荐(0) 编辑
摘要:class Person { ... }; class Student: // 这一次我们 private Person { ... }; // 使用私有继承 void dance(const Person& p); // 每个人会跳舞 void study(const Student& s); // 只有学生才学习 Person p; // p是一个人Student s; // s是一个... 阅读全文
posted @ 2013-05-28 10:52 helloweworld 阅读(170) 评论(0) 推荐(0) 编辑
摘要:该条款实际上讲的是何时使用继承,何时使用模板。 给了两个例子,即采用何种方式实现Stack类和Cat类。 使用模板实现Stack,使用继承实现Cat,为什么? 因为Stack每个对象的行为都一样,改变Stack的参数类型并不会改变行为; 而对于Cat,每个Cat对象行为不一致,需要用虚函数实现不同的行为。 条款最后给出结论: · 当对象的类型不影响类中函数的行为时,就要使用模板来生成这样一组类... 阅读全文
posted @ 2013-05-27 15:18 helloweworld 阅读(229) 评论(0) 推荐(0) 编辑

点击右上角即可分享
微信分享提示