摘要:
1 #include <queue> 2 #include <iostream> 3 using namespace std; 4 5 #define QSIZE 100 6 struct BTree 7 8 { 9 int value; 10 struct BTree* lChild; 11 struct BTree* rChild; 12 }; 13 14 void VisitNode(BTree * T) 15 { 16 cout<<T->value<<" "; 17 } 18 BTree * Insert(BTr 阅读全文
随笔档案-2011年08月
动态规划求解0/1背包问题
2011-08-23 18:08 by Daniel Zheng, 2389 阅读, 收藏, 编辑
摘要:
什么是动态规划?动态规划是一种在数学和计算机科学中使用的,用于求解包含重叠子问题的最优化问题的方法。其基本思想是,将原问题分解为相似的子问题,在求解的过程中通过子问题的解求出原问题的解。动态规划的思想是多种算法的基础,被广泛应用于计算机科学和工程领域。比较著名的应用实例有:求解最短路径问题,背包问题,项目管理,网络流优化等。动态规划在查找有很多重叠子问题的情况的最优解时有效。它将问题重新组合成子问题。为了避免多次解决这些子问题,它们的结果都逐渐被计算并被保存,从简单的问题直到整个问题都被解决。因此,动态规划保存递归时的结果,因而不会在解决同样的问题时花费时间。动态规划只能应用于有最优子结构的问 阅读全文
递归算法的时间复杂度分析[转]
2011-08-23 10:43 by Daniel Zheng, 716 阅读, 收藏, 编辑
摘要:
递归算法时间复杂度的计算方程式一个递归方程: 在引入递归树之前可以考虑一个例子: T(n) = 2T(n/2) + n2 迭代2次可以得: T(n) = n2+ 2(2T(n/4) + (n/2)2) 还可以继续迭代,将其完全展开可得: T(n) = n2+ 2((n/2)2+ 2((n/22)2+ 2((n/23)2+ 2((n/24)2+…+2((n/2i)2+ 2T(n/2i + 1)))…)))) ……(1) 而当n/2i+1== 1时,迭代结束。 将(1)式小括号展开,可得: T(n) = n2+ 2(n/2)2+ 22(n/22)2+ … + 2i(n/2i... 阅读全文
Fibonacci数列计算的三种方法
2011-08-22 21:38 by Daniel Zheng, 2758 阅读, 收藏, 编辑
摘要:
以下分别用递归,迭代,动态规划求解Fibonacci数列: 1 #include <iostream> 2 #include <ctime> 3 using namespace std; 4 5 int Fibonacci_R(int n) 6 { 7 if((n == 1)||(n == 2)) 8 return 1; 9 else10 return Fibonacci_R(n-1) + Fibonacci_R(n-2);11 }12 13 int Fibonacci_I(int n)14 {15 int A = 1; 16 ... 阅读全文
堆内存和栈内存详解[转]
2011-08-22 16:21 by Daniel Zheng, 694 阅读, 收藏, 编辑
摘要:
堆:顺序随意栈:先进后出堆和栈的区别一、预备知识—程序的内存分配一个由c/C++编译的程序占用的内存分为以下几个部分1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放4、文字常量 阅读全文
深入理解递归函数的调用过程[转]
2011-08-22 14:36 by Daniel Zheng, 8637 阅读, 收藏, 编辑
摘要:
下面是个关于递归调用简单但是很能说明问题的例子:/*递归例子*/ 1 #include<stdio.h> 2 void up_and_down(int); 3 int main(void) 4 { 5 up_and_down(1); 6 return 0; 7 } 8 void up_and_down(int n) 9 {10 printf("Level %d:n location %p\n",n,&n); /* 1 */11 if(n<4)12 up_and_down(n+1);13 printf("Level %d:n locatio 阅读全文
带头结点的单链表反转
2011-08-22 14:33 by Daniel Zheng, 508 阅读, 收藏, 编辑
摘要:
1 #include <iostream> 2 using namespace std; 3 4 struct Node 5 { 6 public: 7 int data; 8 Node * pNode; 9 };10 11 12 void CreateList(Node * Header)13 {14 cout<<"Input the node data and end by 0"<<endl;15 int input;16 int count = 0;17 Node * oHeader = Header;18 while(cin> 阅读全文
最长公共子序列问题(转)
2011-08-21 22:24 by Daniel Zheng, 331 阅读, 收藏, 编辑
摘要:
转自http://blog.csdn.net/yysdsyl/article/details/4226630动态规划法经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题。简单地采用把大问题分解成子问题,并综合子问题的解导出大问题的解的方法,问题求解耗时会按问题规模呈幂级数增加。为了节约重复求相同子问题的时间,引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法。【问题】求两字符序列的最长公共字符子序列问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列。令给定 阅读全文
最长公共子串问题
2011-08-21 10:23 by Daniel Zheng, 1081 阅读, 收藏, 编辑
摘要:
最长公共子串问题(longest common substring problem)也就是找到两个或以上的字符串的最长公共子串,该字串在位置上相邻。例如ABAB,BABA,ABBA,最长公共子串为AB。我们可以把该问题定义如下:给出两个字符串S和T,S的长度为m,T的长度为n,找出S与T的最长公共子串。假设S = “ABAB”,T=“BABA”,我们可以构造一个如下的矩阵:ABAB00000B00101A01020B00203A01030对于数组array[m][n],扩展为array[m+1][n+1],这样是为了方便初始化,减少循环中对边界的判断。if( S[i] == T[j] ) ar 阅读全文
汉诺塔问题
2011-08-20 01:16 by Daniel Zheng, 11753 阅读, 收藏, 编辑
摘要:
汉诺塔问题是使用递归解决问题的经典范例。 汉诺(Hanoi)塔问题:古代有一个梵塔,塔内有三个座A、B、C,A座上有64个盘子,盘子大小不等,大的在下,小的在上(如图)。有一个和尚想把这64个盘子从A座移到B座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上。在移动过程中可以利用B座,要求打印移动的步骤。如果只有一个盘子,则不需要利用B座,直接将盘子从A移动到C。如果有2个盘子,可以先将盘子1上的盘子2移动到B;将盘子1移动到c;将盘子2移动到c。这说明了:可以借助B将2个盘子从A移动到C,当然,也可以借助C将2个盘子从A移动到B。如果有3个盘子,那么. 阅读全文
八皇后问题
2011-08-20 01:07 by Daniel Zheng, 424 阅读, 收藏, 编辑
摘要:
八皇后问题是一个国际象棋以为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。 我们定义这样的一个一维数组,数组的下标表示第i行,数组的值表示第i列,数组大小为8,把数组初始化为从0到7的八个不同值。相当与对01234567做全排列,这样所以的数字自然不再同一行,同一列,即数组下标的值各不相同,数组的值各不相同,且都是取从0到7的不同值。 现在要解决的就是对角线的问题,如果两个元素处在同一对角线,则有数组下标之差的绝对值等于数组元素值之差的绝对值。即 abs(i-j) 阅读全文
字符串的全排列问题
2011-08-20 00:35 by Daniel Zheng, 393 阅读, 收藏, 编辑
摘要:
对于一个字符串abc, 求它的全排列可以这样分析:第一个字符为a时,bc的全排列第一个字符为b时,ac的全排列第一个字符为c时,ab的全排列对上述各种情况的子串采用相同的方法,直到子串只有一个字符为止,全排列就是它自身。各处代码:void swap(char * a, char * b){ char temp = *a; *a = *b; *b = temp; }void permutation(char *s, int start, int end) //end = strlen(s){ int i; if (start == end) { ... 阅读全文
常见C语言库函数源码
2011-08-18 15:19 by Daniel Zheng, 2303 阅读, 收藏, 编辑
摘要:
memcpy和memmove功能基本上差不多,但是当源串和目标串有Overlap时,memmove可以正确处理,memcpy则不行。void * __cdecl memcpy (void * dst, const void * src, size_t count){ void * ret = dst; while (count--) { *(char *)dst = *(char *)src; dst = (char *)dst + 1; src = (char *)src + 1; } return(ret);}void * __cdecl memmove (void * dst, cons 阅读全文
第一个 Python 程序
2011-08-16 23:22 by Daniel Zheng, 1675 阅读, 收藏, 编辑
摘要:
这是一个完整的, 可执行的 Python 程序。def buildConnectionString(params): """Build a connection string from a dictionary of parameters. Returns string.""" return ";".join(["%s=%s" % (k, v) for k, v in params.items()])if __name__ == "__main__": myParams = 阅读全文
More Effective C++ 学习笔记(1)
2011-08-16 17:13 by Daniel Zheng, 496 阅读, 收藏, 编辑
摘要:
不要对数组使用多态 类继承的最重要的特性是你可以通过基类指针或引用来操作派生类。这样的指针或引用具有行为的多态性,就好像它们同时具有多种形态。C++允许你通过基类指针和引用来操作派生类数组。不过这根本就不是一个特性,因为这样的代码几乎从不如你所愿地那样运行。假设你有一个类BST(比如是搜索树对象)和继承自BST类的派生类BalancedBST:class BST { ... };class BalancedBST: public BST { ... }; 有这样一个函数,它能打印出BST类数组中每一个BST对象的内容:void printBSTArray(ostream& s, con 阅读全文
Understanding Smart Pointers
2011-08-15 23:10 by Daniel Zheng, 326 阅读, 收藏, 编辑
摘要:
C++ programmers do not necessarily need to use plain pointer types when managing memory on the heap (or the free store); they can make use of smarter option.What Are Smart Pointers?Very simply said, a smart pointer in C++ is a class, with overloaded operators, which behaves like a conventional point 阅读全文
Working with Bit Flags Using STL
2011-08-15 12:39 by Daniel Zheng, 281 阅读, 收藏, 编辑
摘要:
Bits can be very efficient way of storing settings and flags. STL supplies classes that help organize and manipulate bitwise information.The bitset Classstd::bitset is an STL class designed for handling information in bits and bit flags. The std::bitset is not classified as an STL container because 阅读全文
Adaptive Container: stack and queue
2011-08-14 22:53 by Daniel Zheng, 318 阅读, 收藏, 编辑
摘要:
The standard template library (STL) features containers that adapt othersto simulate stack and queue behavior. Such containers that internally useanother and present a distinct behavior are called adaptive containers.Using the STL stack ClassThe STL stack is a generic class that allows insertions an 阅读全文
STL Algorithms
2011-08-14 20:25 by Daniel Zheng, 349 阅读, 收藏, 编辑
摘要:
One important part of the standard template library is a set of generic functions, supplied by the header <algorithm>. that help manipulate or work with the contents of a container.What Are STL Algorithms?Finding, searching, removing, and counting are some generic algorithmic activities that f 阅读全文
Understanding Function Objects
2011-08-13 00:24 by Daniel Zheng, 304 阅读, 收藏, 编辑
摘要:
Function objects or functors might sould exotic or intimidating, but they are entities of C++ that you have probably seen if not also used, without having realized it.The Concept of Function Objects and PredicateOn a conceptual level, function objects are objects that work as function. On an impleme 阅读全文
STL map and multimap
2011-08-12 10:02 by Daniel Zheng, 395 阅读, 收藏, 编辑
摘要:
A Brief IntroductionThe map and multimap are key-value pair containers that allow for a lookup on the basis of a key. The difference between the map and multimap is that only the latter allows for duplicates, whereas the former can store only unique keys.Th facilitate quick searching, STL implementa 阅读全文
STL set and multiset
2011-08-11 23:48 by Daniel Zheng, 384 阅读, 收藏, 编辑
摘要:
The set and multiset are containers that facilitate a quick lookup of keys in a container that stores them; that is, the keys are the values stored in the one-dimensional container.The difference between the set and the multiset is that latter allows for duplicates whereas the former can store only 阅读全文
STL list
2011-08-11 17:03 by Daniel Zheng, 374 阅读, 收藏, 编辑
摘要:
The standard template library supplies the programmer with a doubly linked list in the form of template class std::list.STL's list class allows for constant time insertions at the front, back, or middle of the sequence.Basic list OperationsBefore use it, you need to include the header file <l 阅读全文
STL Dynamic Array Classes
2011-08-11 01:26 by Daniel Zheng, 368 阅读, 收藏, 编辑
摘要:
Dynamic arrays supply the programmer with the flexibility of storing data without needing to know the exact volume thereof at the time of programming the application, the way static arrays do. Naturally, this is a frequently needed requirement and the STL supplies a ready-to-use solution in the form 阅读全文
The STL string Class
2011-08-11 00:49 by Daniel Zheng, 360 阅读, 收藏, 编辑
摘要:
The STL string class std::string helps you in the following ways:Reduces the effort of creation and manipulating stringsIncreases the stability of the application being programmed by internally managing memory allocation detailsSupplies copy constructor and assignment operators that automatically en 阅读全文
An Introduction to the Standard Template Library
2011-08-10 15:23 by Daniel Zheng, 245 阅读, 收藏, 编辑
摘要:
STL consist of three components:Container for storing informationIterators for accessing the information storedAlgorithms for manipulating the content of the containersSTL ContainersContainers are STL classes that are used to store data. There are two types of container classes:Sequential containers 阅读全文
Linux正则表达式--基础正则表示法
2011-08-09 23:00 by Daniel Zheng, 2014 阅读, 收藏, 编辑
摘要:
基础正规表示法(出自鸟哥的LINUX私房菜) 既然正规表示法是处理字符串的一个标准表示方式,他需要支持的工具程序来辅助, 所以,我们这里就先介绍一个最简单的字符串撷取功能的工具程序,那就是 grep 啰! 在介绍完 grep 的基本功能之后,就进入正规表示法的特殊字符的处理能力了。 [root@test root]# grep [-acinv] '搜寻字符串' filename参数说明:-a :将 binary 档案以 text 档案的方式搜寻数据-c :计算找到 '搜寻字符串' 的次数-i :忽略大小写的不同,所以大小写视为相同-n :顺便输出行号-v :反向 阅读全文
Makefile中的常用变量与函数
2011-08-09 15:59 by Daniel Zheng, 1924 阅读, 收藏, 编辑
摘要:
Makefile中的预定义变量:CC,C语言编译器的名称,ccCPP, C语言预处理器的名称,$(CC) -ECXX, C++语言的编译器名称,g++RM,删除文件程序的名称,rm -fCFLAGS, C语言编译器的编译选项,无默认值CPPFLAGS,C语言预处理器的编译选项,无默认值CXXFLAGS,C++语言编译器的编译选项,无默认值注:在使用RM时,一般使用如下语句: -$(RM) $(TARGET) $(OBJS), 符号“-”表示在操作失败时不报错,而是继续执行。例如在不存在TARGET时将继续删除OBJS。Makefile中的自动变量:$*, 表示目标文件的名称,不包含扩展名$@, 阅读全文
Effective C++ 学习笔记(27)
2011-08-09 11:38 by Daniel Zheng, 263 阅读, 收藏, 编辑
摘要:
弄清C++在幕后为你所写,所调用的函数 一个空类什么时候不是空类?---- 当C++编译器通过它的时候。如果你没有什么下列函数,那么编译器会自动声明它自己的版本。这些函数就是:一个拷贝构造函数,一个赋值运算符,一个析构函数,一对取址运算符。如果你没有声明如何构造函数,那么它也会为你声明一个缺省构造函数。所以这些函数都是public。class Empty {}; 和下面是一样的:class Empty{public: Empty(); Empty(const Empty & rhs); ~Empty(); Empty & operator=(const Empty & 阅读全文
Effective C++ 学习笔记(26)
2011-08-07 18:27 by Daniel Zheng, 186 阅读, 收藏, 编辑
摘要:
说你想说的;理解你所说的 在本章关于 "继承和面向对象设计" 的简介中,我曾强调,理解不同的面向对象构件在C++中的含义十分重要。这和仅仅知道C++语言的规则有很大的不同。例如,C++规则说,如果类D 从类B 公有继承,从D 的指针到B 的指针就有一个标准转换;B 的公有成员函数将被继承为D 的公有成员函数,等等。这些规则都是正确的,但在将设计思想转化为C++的过程中,它们起不到任何作用。相反,你需要知道,公有继承意味着 "是一个",如果D 从B 公有继承,类型D 的每一个对象也 "是一个" 类型B 的对象。因而,如果想在设计中表示 阅读全文
Effective C++ 学习笔记(25)
2011-08-07 18:14 by Daniel Zheng, 356 阅读, 收藏, 编辑
摘要:
明智的使用私有继承 C++将公有继承视为 "是一个" 的关系。例如:某个类层次结构中,Student 类从Person 类公有继承,为了使某个函数成功调用,编译器可以在必要时隐式地将Student 转换为Person。这个例子很值得再看一遍,只是现在,公有继承换成了私有继承: class Person { ... };class Student:private Person { ... }; // 使用私有继承void dance(const Person& p); // 每个人会跳舞void study(const Student& s); // 只有学生 阅读全文
Effective C++ 学习笔记(24)
2011-08-07 17:52 by Daniel Zheng, 237 阅读, 收藏, 编辑
摘要:
通过分层来体现“有一个”或“用...来实现” 使某个类的对象成为另一个类的数据成员,从而实现将一个类构筑在另一个类之上,这一过程称之为“分层”。例如: class Address {...};class PhoneNumber {...};class Person{public: ...private: string name; Address address; PhoneNumber voiceNumber; PhoneNumber faxNumber;}; 本例中,Person 类被认为是置于string,Address 和PhoneNumber 类的上层,因为它包含那些类型的数据成员。& 阅读全文
Effective C++ 学习笔记(23)
2011-08-07 13:40 by Daniel Zheng, 207 阅读, 收藏, 编辑
摘要:
决不要重新定义继承而来的缺省参数值#include <iostream>using namespace std;enum color{ RED,GREEN,BLACK,WHITE};class Base{public: virtual void ShowColor(color myColor = BLACK) { cout<<"Base Color is "<<myColor<<endl; }};class Derived:public Base{public: virtual void ShowColor(color myC 阅读全文
Effective C++ 学习笔记(22)
2011-08-07 13:17 by Daniel Zheng, 218 阅读, 收藏, 编辑
摘要:
决不要重新定义继承而来的非虚函数 假设类 D 公有继承于类B,并且类B 中定义了一个公有成员函数mf。mf的参数和返回类型不重要,所以假设都为void。换句话说,我这么写: class B {public: void mf(); ...};class D: public B { ... }; 甚至对B,D 或mf 一无所知,也可以定义一个类型D 的对象x, D x; // x 是类型D 的一个对象 那么,如果发现这么做:B *pB = &x; // 得到x 的指针pB->mf(); // 通过指针调用mf 和下面这么做的执行行为不一样:D *pD = &x; // 得到x 阅读全文
Effective C++ 学习笔记(21)
2011-08-07 00:01 by Daniel Zheng, 256 阅读, 收藏, 编辑
摘要:
使公有继承体现“是一个”的含义 C++面向对象编程中一条重要的规则是:公有继承意味着 "是一个"。 当写下类 D("Derived" )从类B("Base")公有继承时,你实际上是在告诉编译器(以及读这段代码的人):类型D 的每一个对象也是类型B 的一个对象,但反之不成立;你是在说:B 表示一个比D 更广泛的概念,D 表示一个比B 更特定概念;你是在声明:任何可以使用类型B 的对象的地方,类型D 的对象也可以使用,因为每个类型D 的对象是一个类型B 的对象。相反,如果需要一个类型D 的对象,类型B 的对象就不行:每个D "是 阅读全文
Effective C++ 学习笔记(20)
2011-08-06 18:34 by Daniel Zheng, 178 阅读, 收藏, 编辑
摘要:
千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用 先看第一种情况:返回一个局部对象的引用。它的问题在于,局部对象 ----- 顾名思义 ---- 仅仅是局部的。也就是说,局部对象是在被定义时创建,在离开生命空间时被销毁的。所谓生命空间,是指它们所在的函数体。当函数返回时,程序的控制离开了这个空间,所以函数内部所有的局部对象被自动销毁。因此,如果返回局部对象的引用,那个局部对象其实已经在函数调用者使用它之前被销毁了。 当想提高程序的效率而使函数的结果通过引用而不是值返回时,这个问题就会出现。 class Rational { // 一个有理数类public: Ration 阅读全文
Effective C++ 学习笔记(19)
2011-08-06 18:21 by Daniel Zheng, 228 阅读, 收藏, 编辑
摘要:
避免这样的成员函数:其返回值是指向成员的非const 指针或引用,但成员的访问级别比这个函数要低 使一个成员为 private 或protected 的原因是想限制对它的访问,对吗?劳累的编译器要费九牛二虎之力来确保你设置的访问限制不被破坏,对不对?所以,写个函数来让用户随意地访问受限的成员没多大意义,对不对?如果你确实认为有意义,那么请反复阅读本段,直到你不这样认为为止。 实际编程中很容易违反这条规则,下面是个例子: class Address { ... }; // 某人居住在此class Person {public: Address& personAddress() { ret 阅读全文
Effective C++ 学习笔记(18)
2011-08-06 09:45 by Daniel Zheng, 224 阅读, 收藏, 编辑
摘要:
如果不想使用隐式生成的函数就要显式地禁止它假设想写一个类模板 Array,它所生成的类除了可以进行上下限检查外,其它行为和C++标准数组一样。设计中面临的一个问题是怎么禁止掉Array 对象之间的赋值操作,因为对标准C++数组来说赋值是不合法的: double values1[10];double values2[10];values1 = values2; // 错误! 对很多函数来说,这不是个问题。如果你不想使用某个函数,只用简单地不把它放进类中。然而,赋值运算符属于那种与众不同的成员函数,当你没有去写这个函数时,C++会帮你写一个。那么,该怎么办呢? 方法是声明这个函数(operator 阅读全文
c++继承中的内存布局 <转>
2011-08-06 00:52 by Daniel Zheng, 504 阅读, 收藏, 编辑
摘要:
今天在网上看到了一篇写得非常好的文章,是有关c++类继承内存布局的。看了之后获益良多,现在转在我自己的博客里面,作为以后复习之用。——谈VC++对象模型(美)简.格雷程化 译译者前言一个C++程序员,想要进一步提升技术水平的话,应该多了解一些语言的语意细 节。对于使用VC++的程序员来说,还应该了解一些VC++对于C++的诠释。 Inside the C++ Object Model虽然是一本好书,然而,书的篇幅多一些,又和具体的VC++关系小一些。因此,从篇幅和内容来看,译者认为本文是深入理解C++对象模型比较好 的一个出发点。这篇文章以前看到时就觉得很好,旧文重读,感觉理解得更多一些了,于 阅读全文
Effective C++ 学习笔记(17)
2011-08-06 00:09 by Daniel Zheng, 193 阅读, 收藏, 编辑
摘要:
在函数重载和设定参数缺省值间慎重考虑会对函数重载和设定参数缺省值产生混淆的原因在于,它们都允许一个函数以多种方式被调用:void f(); // f 被重载void f(int x);f(); // 调用 f()f(10); // 调用f(int)void g(int x = 0); // g 有一个// 缺省参数值g(); // 调用 g(0)g(10); // 调用 g(10) 那么,什么时候该用哪种方法呢? 答案取决于另外两个问题。第一,确实有那么一个值可以作为缺省吗?第二,要用到多少种算法?一般来说,如果可以选择一个合适的缺省值并且只是用到一种算法,就使用缺省参数。否则,就使用函数重载 阅读全文
Effective C++ 学习笔记(16)
2011-08-04 21:46 by Daniel Zheng, 258 阅读, 收藏, 编辑
摘要:
必须返回一个对象时不要试图返回一个引用看一个表示有理数的类,其中包含一个友元函数,用于两个有理数相乘:class Rational {public: Rational(int numerator = 0, int denominator = 1); ...private: int n, d; // 分子和分母friend const Rational // 参见条款21:为什么 operator*(const Rational& lhs, // 返回值是const const Rational& rhs)};inline const Rational operator*(con 阅读全文
Effective C++ 学习笔记(15)
2011-08-04 12:03 by Daniel Zheng, 218 阅读, 收藏, 编辑
摘要:
尽量使用“传引用”而不是“传值” C 语言中,什么都是通过传值来实现的,C++继承了这一传统并将它作为默认方式。除非明确指定,函数的形参总是通过“实参的拷贝”来初始化的,函数的调用者得到的也是函数返回值的拷贝。 “通过值来传递一个对象”的具体含义是由这个对象的类的拷贝构造函数定义的。这使得传值成为一种非常昂贵的操作。例如,看下面这个(只是假想的)类的结构: class Person{public: Person(); ~Person(); ...private: string name, address;};class Student:public Person{public: Student 阅读全文
Effective C++ 学习笔记(14)
2011-08-03 23:59 by Daniel Zheng, 288 阅读, 收藏, 编辑
摘要:
在operator=中检查给自己赋值的情况做类似下面的事时,就会发生自己给自己赋值的情况:class X { ...};X a;a = a; 这种事做起来好象很无聊,但它完全是合法的,所以看到程序员这样做不要感到丝毫的怀疑。更重要的是,给自己赋值的情况还可以以下面这种看起来更隐蔽的形式出现:a = b; 如果 b 是a 的另一个名字(例如,已被初始化为a 的引用),那这也是对自己赋值,虽然表面上看起来不象。这是别名的一个例子:同一个对象有两个以上的名字。在本条款的最后将会看到,别名可以以大量任意形式的伪装出现,所以在写函数时一定要时时考虑到它。 在赋值运算符中要特别注意可能出现别名的情况,其理 阅读全文
Effective C++ 学习笔记(13)
2011-08-03 22:57 by Daniel Zheng, 200 阅读, 收藏, 编辑
摘要:
在operator=中对所有数据成员赋值template<class T>class NamedPtr{public: NamedPtr(const string & initName, T * initPtr); NamedPtr & operator= (const NamedPtr & rhs);private: string name; T * ptr;};template<class T>NamedPtr<T> & NamedPtr<T>::operator=(const NamedPtr<T> 阅读全文
Effective C++ 学习笔记(12)
2011-08-03 16:03 by Daniel Zheng, 193 阅读, 收藏, 编辑
摘要:
让operator=返回*this的引用要完成如 a = b =c 这样的操作所以返回值不能为void,对这个表达式,编译器的理解为 a = (b = c),所以operator=可以返回左值或者右值,但有时候我们也需要这样的操作 (a = b) = c ,b赋值给a,然后c赋值给a。所以operator=应该返回右值。、由此分析,我们得到operator=的函数声明为 T & T::operator=(const T &)。假设我们传入的参数为a,则a为const T & 类型,与返回类型不符,所以不能作为返回值。如果我们去掉参数的const,首先,这样不安全,函数内 阅读全文
Effective C++ 学习笔记(11)
2011-08-03 15:01 by Daniel Zheng, 242 阅读, 收藏, 编辑
摘要:
确定基类有虚析构函数class A{public: A() { cout<<"A constructor"<<endl; } ~A() { cout<<"A destructor"<<endl; }};class B: public A{public: B() { cout<<"B constructor"<<endl; } ~B() { cout<<"B destructor"<<endl; }};int main() 阅读全文
Effective C++ 学习笔记(10)
2011-08-03 14:28 by Daniel Zheng, 216 阅读, 收藏, 编辑
摘要:
初始化列表中的成员列出的顺序和它们在类中声明的顺序相同class A{public: A(int a):j(a),i(j*2) { cout<<"A constructor"<<endl; } void Get() const { cout<<"i="<<i<<endl<<"j="<<j<<endl; }private: int i; int j;};int main(){ A a(10); a.Get(); return 0;} 执行结果 阅读全文
Effective C++ 学习笔记(9)
2011-08-03 14:12 by Daniel Zheng, 234 阅读, 收藏, 编辑
摘要:
尽量使用初始化而不是在构造函数里赋值class Test{ public: int a; float b; Test():a(0),b(0.0) { } Test() { a=0; b=0.0; }}; 初始化与赋值构造函数对内置类型区别不大,而对于非内置类型,如string,为了避免两次构造函数的调用,推荐使用初始化。以下是必须使用初始化的情况:对于const和引用类型,只能初始化,不能赋值。如果我们的类A有一个类B的成员,而类B没有默认构造函数,而只有带参数的构造函数,这个时候要对类B进行初始化,只能调用初始化表。class A{public: A(int a) { cout<< 阅读全文