上一页 1 2 3 4 5 6 7 ··· 9 下一页
摘要: 下面再来看书,去理解书上说的Handler classes就简单多了,我们大概过一下。假设我们要写一个Person类,如下: 1 class Person 2 { 3 private: 4 string name; 5 MyDate birthday; 6 MyAddress address; 7 8 public: 9 // fallows functions10 // ...11 };这个Person类里面包含有人的名字,人的生日以及地址,还有一些没有列出来的方法。注意到这里用到了string(它不是一个class,只是一个typedef,大多数情... 阅读全文
posted @ 2014-02-16 22:10 Jerry19880126 阅读(1603) 评论(3) 推荐(4) 编辑
摘要: 在说这一条款之前,先要了解一下C/C++的编译知识,假设有三个类ComplexClass, SimpleClass1和SimpleClass2,采用头文件将类的声明与类的实现分开,这样共对应于6个文件,分别是ComplexClass.h,ComplexClass.cpp,SimpleClass1.h,SimpleClass1.cpp,SimpleClass2.h,SimpleClass2.cpp。ComplexClass复合两个BaseClass,SimpleClass1与SimpleClass2之间是独立的,ComplexClass的.h是这样写的:#ifndef COMPLESS_CLAS 阅读全文
posted @ 2014-02-16 22:07 Jerry19880126 阅读(3843) 评论(3) 推荐(6) 编辑
摘要: 学过基本程序课的同学都知道,inline是内联的关键字,它可以建议编译器将函数的每一个调用都用函数本体替换。这是一种以空间换时间的做法。把每一次调用都用本体替换,无疑会使代码膨胀,但可以节省函数调用的成本,因为函数调用需要将之前的参数以堆栈的形式保存起来,调用结束后又要从堆栈中恢复那些参数。但注意inline只是对编译器的一个建议,编译器并不表示一定会采纳,比如当一个函数内部包含对自身的递归调用时,inline就会被编译器所忽略。对于虚函数的inline,编译器也会将之忽略掉,因为内联(代码展开)发生在编译期,而虚函数的行为是在运行期决定的,所以编译器忽略掉对虚函数的inline。对于函数指针 阅读全文
posted @ 2013-09-21 21:27 Jerry19880126 阅读(1362) 评论(5) 推荐(3) 编辑
摘要: 还是举书上的例子:1 void PrettyMenu::changeBackground(std::istream& imgSrc)2 {3 lock(&mutex);4 delete bgImage;5 ++ imageChanges;6 bgImage = new Image(imgSrc);7 unlock(&mutex);8 }这段代码大致的意思就是改变背景图片,删掉旧的背景图片,记录修改次数,然后创建新的背景图片。考虑到多线程操作,所以这里用了lock和unlock。但这里会出现问题,因为并不是每次new都会成功的,有可能抛出异常,一旦抛出异常... 阅读全文
posted @ 2013-09-08 20:24 Jerry19880126 阅读(1141) 评论(0) 推荐(0) 编辑
摘要: 举个例子: 1 class Student 2 { 3 private: 4 int ID; 5 string name; 6 public: 7 string& GetName() 8 { 9 return name;10 }11 };这是一个学生的类,类里面有两个成员变量,一个是学生ID,用整数表示,另一个是姓名,用string表示。有一个公有的方法GetName(),获得学生的名字,根据条款20所说的,使用引用可以防止资源不必要地拷贝,那么在返回值这边就用string&。但现在问题来了,这个函数只是想返回学生的姓名,并不想用户对之进... 阅读全文
posted @ 2013-06-29 21:08 Jerry19880126 阅读(788) 评论(0) 推荐(0) 编辑
摘要: 有关转型的几种做法,已经在早些的博客中写过了。这里先简单回顾一下,再讲一讲effective中对之更深入的阐述。转型可以按风格可以分成C风格转型和C++风格转型两大类,C风格转型很容易看到,因为我们会经常使用,像(T) expression以及:T (expression)最经典的例子就是处理整数除法,在C/C++程序中,整数除法的结果还是整数,有时会得不到我们想到的结果,比如3/5,结果是0,而不是0.6,但如果这样double(3) / 5,结果就会是0.6了,因为转型操作double(3),将整数转成了浮点数,这样就是小数除法了,可以得到带小数点的结果。C++风格的转型操作分成四类:co 阅读全文
posted @ 2013-06-29 17:20 Jerry19880126 阅读(1231) 评论(0) 推荐(0) 编辑
摘要: 这个条款从字面意思还是很好理解的,就是在使用这个变量前才去定义,而不是很早就定义了它,而在很后面的时候才去使用。这个条款只适用于对变量声明位置没有要求的语言,比如C++。对于像C或者一些脚本语言,语法要求变量声明放在函数开始处,这个条款就不能使用了。但其实从使用的角度而言,如果不是语法的硬性要求,还是在变量使用前再去定义变量的做法比较好。这有几点原因,最直观的就是可读性比较好,程序员在阅读代码时,看到一个陌生的变量名,不用向上翻好几页才看到它的定义类型,而且对于开发者而言,也不会出现前面定义了一个变量,之后又忘记使用它的情况。另一个原因就是可以节省资源,考虑以下的代码:1 void examp 阅读全文
posted @ 2013-06-29 10:56 Jerry19880126 阅读(850) 评论(0) 推荐(0) 编辑
摘要: 我也不知道为什么作者给这个条款起这样的名字,因为这样看上去重点是在“不抛出异常”,但事实上作者只是在全文最后一段说了一下不抛异常的原因,大部分段落是在介绍怎样写一个节省资源的swap函数。你可以试一下,只要包含了头文件iostream,就可以使用swap函数,比如:1 #include <iostream>2 3 int main()4 {5 int a = 3;6 int b = 4;7 std::swap(a, b);8 }结果就是a为4,b为3了,也就是说,在std的命名空间内,已经有现成的swap的函数了,这个swap函数很简单,它看起来像这样:1 templa... 阅读全文
posted @ 2013-06-16 22:13 Jerry19880126 阅读(1487) 评论(1) 推荐(1) 编辑
摘要: 还是举书上的有理数例子: 1 class Rational 2 { 3 private: 4 int numerator; 5 int denominator; 6 public: 7 Rational(int n = 0, int d = 1): numerator(n), denominator(d){assert(denominator != 0);} 8 int GetNumerator() const{return numerator;} 9 int GetDenominator() const {return denominator;}10 ... 阅读全文
posted @ 2013-06-16 16:58 Jerry19880126 阅读(829) 评论(0) 推荐(0) 编辑
摘要: 本条款还是讨论封装的问题,举书上的例子:1 class WebBrower2 {3 public:4 void ClearCach();5 void ClearHistory();6 void RemoveCookies();7 };定义了一个WebBrower的类,里面执行对浏览器的清理工作,包括清空缓存,清除历史记录和清除Cookies,现在需要将这三个函数打包成一个函数,这个函数执行所有的清理工作,那是将这个清理函数放在类内呢,还是把他放在类外呢?如果放在类内,那就像这样: 1 class WebBrower 2 { 3 … 4 void Clea... 阅读全文
posted @ 2013-06-16 10:40 Jerry19880126 阅读(1310) 评论(0) 推荐(0) 编辑
上一页 1 2 3 4 5 6 7 ··· 9 下一页