| ||||
| Purpose :这是一份对于C++初学者来说需要熟练掌握的基础知识文档 Plan on updating :我会先写一份,大家有兴趣的话参加讨论,等讨论和意见结束我整理成FAQ,并将之放在本置顶贴里,供以后本论坛的同仁学习参阅。而且我会根据本坛所提出的问题进行总结,不定期的更新和添加内容。学疏才浅,难免有不周或错误之处,如果发现错误,请及时与我联系。谢谢大家的支持,我会不断改进。非常欢迎各位有兴趣的同志添加内容,同样的办法,在大家讨论结束后,我会整理并加入本FAQ。有意者请利用论坛消息联系我。 Acknowledgement :在此特别感谢abp,pora和各位参与讨论的同仁对我的支持和鼓励。 Copyright :http://www.allaboutprogram.com网站 2003, all right reserved |
| ||||
| //Author :CodingGirl //Thanks :在此感谢Innocentius和众位热心朋友对某些知识点的指导和修正 //Copyright :http://www.allaboutprogram.com 2003, all right reserved FAQ 1. 对象初始化-----构造函数,拷贝构造函数和operator = 一个具有良好结构骨干的,明确意义和定义良好的class,是对象间良好合作的重要条件(强调类设计的内聚性和完整性),为了做到这一点在设计类时类的拷贝构造、析构和赋值是类设计者应该考虑的;什么时候应该仔细考虑他们呢?一个基本准则即是:当一个class里有动态配置的内存(或有指向其他不可共享的资源)的时候,请为此class手动撰写拷贝构造(copy constructor)、析构(dtor)和赋值(operator = )函数; 不管class符不符合这个基本准则,也请你确信已经考虑过他们 首先分清initialization(初始化)和assignment(赋值),对象的初始化发生在它初次获得一个值的时候,对于带有constructors(构造函数)的class或struct,初始化会调用某个构造函数完成。这和assignment不同,assignment发生在“已初始化的对象被赋予新值”,所以区分下列动作: 代码:
代码:
代码:
需要记住的一点就是,当你没有显式的提供这两个函数的时候,C++会产生一个默认的copy ctor和operator=并调用之,而且默认产生的operator=会执行memberwise assigment(一个一个的拷贝),对指针而言就是按位拷贝(bitwise copy)。 如果这样用Man定义: Man man_1("CodingGirl"); Man man_2("Programmer"); man_1 = man_2; //由于operator=这个动作,原class作者并没有给出定义,所以编译器会产生默认的operator =,并将man_2的内容逐个赋值给man_1相对应的member。这种动作对于指针而言是很危险的,那意味着man_1和man_2中各自的namePtr都指向含有字符串“Programmer”的这块内存。这样做的后果是:1.man_1原先所指的内存(存放"CodingGirl"的那块)由于没有delete,所以永远的丢失了,这就是所谓的memory leak(内存泄漏)。2. man_1 , man_2中各自的指针namePtr都指向相同的字符串,当其中一个,比如man_1先离开其作用域范围时,先离开的这个对象man_1会调用自己的dtor删除这块内存,但这块内存仍然被另一个man_2的指针所指,这是一个很危险的动作。比如: 代码:
当你熟悉了所有这一切之后,可以提炼ctor,copy ctor和dtor中共同的初始化部分 而改成下列的代码: 代码:
以上问题参阅书籍: The C++ Program Language (Bjarne Stroustrup(简称:TCPL)) ISO 14882 Programming Languges -- C++ ( C++标准委员会(ISO C++标准)) C++ Primer (Stanley B.Lippman) C++ Primer(3/e) Answer Book Effective C++ (Scott Meyers) More Effective C++ (Scott Meyers) C++ FAQs (2nd Edition) (Marshall cline) 关于FAQ01内容的相关讨论请详见这里: http://www.allaboutprogram.com/bb/viewtopic.php?t=1186
__________________ 世纷纷兮,心胡乱 霜寒寒兮,魂不归 诚烈烈兮,愁不化 |
| ||||
| ABP C++ FAQ02-------------essential const 常变量, const和变量 1.const int x = 8; 常指针 ,const和指针 2.const int *ptr = &x ; 3.int const *ptr = &x ; 4.int * const ptr = &x ; 5.const int * const ptr = &x; const和引用 6.const int &i= x; 和int const &j = y; 常函数 const和函数 7.const int func(int p) 8.const int *func(int *p); 9.int func (int p) const; 10.int func (const int *p); 11.const int func (const int *p) const 常对象 12.常对象const A a , A const a; 13.mutable关键字 1.const int x = 8; const限定修饰符把一个对象转换成一个常量,所以现在x是只读的(read-only)。 2.const int *ptr = &x ; 这里const修饰的是*ptr ,ptr是一个指向int类型的,被定义成const的对象的指针。这意味着,可以赋给ptr其他变量的地址值,但不能修改ptr指向的值。被定义成const对象的指针可以指向常量或非常量的对象。即: 代码:
代码:
const对象的地址只能赋值给指向const对象的指针。 3.int const *ptr = &x ; 除了const的位置不同,作用,意义和2里相同。 4.int * const ptr = &x ; 这里const修饰的是ptr,ptr是一个指向int类型对象的const指针。这意 味着,不能赋给ptr其他变量的地址值,但可以修改ptr指向的值。所以 const常量对象不能被赋给同类型的const指针,即: 代码:
把3,4结合起来 6.const int &i= x; 和int const &j = y; 引用实际就是变量的别名,初始化后,在别名的生存期内,只能和其变量本身关联而不能再指向其它变量,任何对引用的改变都将改变原变量。引用和变量本身是指向同一内存地址的。用const修饰引用,const加在数据类型前后均可,即: const int &i= x;和int const &j = y;虽然形式不同,但实质一样 代码:
func函数返回一个常量对象。这个返回值可以赋给const或非const对象,因为他返回的是一份拷贝。 代码:
8.const int *func(int *p); func函数返回一个常量地址。 代码:
常函数,这种形式只能用于修饰类的成员函数,作用:在常函数中不能改变本类数据成员值,不能用于全局函数和静态成员函数。比如: 代码:
注意点:可以把非const成员函数重载为const成员函数,反之亦然。 10.int func (const int *p); 修饰func函数的参数,使得参数不被在函数体func内修改。 11.const int func (const int *p) const 把7,8,9结合起来 12.常对象const A a , A const a; const修饰对象,const加在数据类型前后均可,const对象只能调用该对象的const成员函数。 13.Mutable关键字。 提到const不得不提一下mutable。看如下的例子: 代码:
代码:
代码:
代码:
http://www.allaboutprogram.com/bb/viewtopic.php?t=1329
__________________ 世纷纷兮,心胡乱 霜寒寒兮,魂不归 诚烈烈兮,愁不化 |
| ||||
| FAQ03:C++中的内部连接与外部连接(上) -----作者:SpitFire 代码:
http://www.allaboutprogram.com/bb/viewtopic.php?t=1612 |