cpp学习摘要.docx
- 文档编号:28172654
- 上传时间:2023-07-09
- 格式:DOCX
- 页数:8
- 大小:19.76KB
cpp学习摘要.docx
《cpp学习摘要.docx》由会员分享,可在线阅读,更多相关《cpp学习摘要.docx(8页珍藏版)》请在冰豆网上搜索。
cpp学习摘要
cpp学习摘要
1.C++编译器不允许任何成员函数调用const对象,除非该成员函数本身也声明为const,即使get成员函数不修改对象时也是这样。
2.声明const的成员函数不能修改对象,因为编译器不允许其修改对象。
在const对象的构造函数调用中调用非const成员函数时是合法的。
3.const对象不能用赋值语句修改,因此应初始化。
类的数据成员声明为const时.要用成员初始化值向构造函数提供类对象数据成员的初始值。
4.所有数据成员都可以用成员初始化值的语法进行初始化,但const和引用必须用这种方式进行初始化。
5.常量类成员(const对象和const“变量”)要用成员初始化值的语法初始化,而不能用赋值语句。
6.如果成员函数不修改对象,最好将其声明const。
如果不需要生成该类的const类型对象,则这样做是没有必要的。
但将这种成员函数声明为const有一个好处,如果不小心修改了这个成员函数中的对象,则编泽器全产生一个语法错误的消息。
友元函数与友元类
1.尽管类定义中有友元函数的原型,但友元仍然不是成员函数。
2.private、protected和public的成员访问符号与友元关系的声明无关,因此友元关系声明可以放在类定义中的任何地方。
3.将类中所有友元关系的声明放在类的首部,不要在其前面加上任何成员访问说明符。
4.友元关系是”给予”的,而不是”索取”的,即要让B成为A的友元,A要显式声明B为自己的友元。
5.
使用this指针
1.每个对象都可以通过this指针访问自己的地址。
对象的this指针不是对象本身的一部分,即this指针不在对该对象进行sizeof操作的结果中体现。
但this指针在每次非static成员函数调用对象时作为第一个隐式参数传递给对象(通过编译器)。
2.this指针隐式引用对象的数据成员和成员函数(当然也可以显式使用)。
this指针的类型取决于对象类型和使用this的成员函数是否声明为const。
在Employee类的非常量成员函数中,this指针的类型为Employee*const(Employee对象的常量指针)。
在Employee类的常量成员函数中,this指针的类型为constEmployee*const(为常量Employee对象的常量指针)。
3.this指针的另一用法是允许连续使用成员函数调用。
动态内存分配与new和delete运算符
1.new和delete运算符提供了比C语言的malloc和free函数调用更好的动态分配内存方法(对任何内部或用户自定义类型)。
考虑下列代码:
TypeName*typeNamePtr;
在ANSIC语言中,要为TypeName类型对象动态分配内存,可以用下列语句:
typeNamePtr=malloc(sizeof(TypeName));
这就要求调用malloc函数和显式使用sizeof运算符,在ANSIC之前的C语言版本中,还要将malloc返回的指针进行类型转换(TypeName*)。
malloe函数中没有提供初始化所分配内存块的方法。
而在C++中,只要用下列语句;
typeNamePtr=newTypeName;
2.new运算符自动生成正确长度的对象并调用对象构造函数和返回正确类型的指针。
如果new无法找到内存空间,则它在ANSI/ISOC++草案标准之前的C++版本中返回。
要在C++中释放这个对象的空间,就要用delete运算符,如下所示:
deletetypeNamePtr;
3.C++允许对新生成的对象提供初始化值,如下所示:
float*thingPtr=newfloat(3.14159);
将新生成的对象float初始化为3.14159。
可以生成10个元素的整型数组并赋给arrayPtr,如下所示:
int*arrayPtr=newint[10];
这个数组可以用下列语句删除:
delete[]arrayPtr;
可以看出,使用neW和delete而不用malloc和free还有其他好处。
neW自动调用构造函数,delete自动调用析构函数。
4.将new和delete动态分配内存的方法与malloc和free动态分配内存的方法混合使用是个逻辑错误:
malloc分配的空间无法用delete释放,new生成的对象无法用free删除。
5.用delete而不是delete[]删除数组可能导致运行时的逻辑错误。
为了避免这个问题,数组生成的内存空间要用delete[]运算符删除,各个元素生成的内存空间要用delete运算符删除。
7.7static类成员
1.类的每个对象有自己的所有数据成员的副本,有时类的所有对象应共享变量的一个副本,因此可以使用static类变量。
stattic类变量表示的是类范围中所有对象共享的信息。
static类成员的声明以static关键字开始。
2.如果一个数据副本就足够使用,用static数据成员可以节省存储空间。
3.Employee类的对象不存在时,仍然可以引用成员count,但只能通过调用static成员函数getCount:
Employee:
:
getCount()
但如果有实例化的对象,则可以通过一个对象调用函数getCount,见第97行和第98行的语句:
cout<<"Numberofemployeesafterinstantiationis"
<
注意,调用e2Ptr->getCount()和Employee:
:
getCount()也能使上述语句运行。
有些公司的软件工程标准要求所有static成员函数只能对类名句柄调用,而不能对对象句柄调用。
4.如果成员函数不访问非static类数据成员和成员函数,则可以声明为static。
与非static成员函数不同的是,static成员函数没有this指针,因为static类数据成员和成员函数是独立于类对象而存在的。
5.在static成员函数中引用this指针是个语法错误。
将static成员函数声明为const是个语法错误。
即使在类没有实例化任何对象时,类的static数据成员和成员函数就已经存在并可使用。
6.删除动态分配内存后,设置指向该内存的指针指向0,辽样就切断了指针与前面所分配内存的连接。
7.8数据抽象与信息隐藏
1.类通常对类的客户隐藏其实现细节,即所谓的信息隐藏。
7.9容器类与迭代
1.最常见的类型包括容器类(containerclass),也称集合类(collectionclass),是保存一组对象集合的类。
容器类通常提供插入、删除、查找、排序和测试类成员项目等操作。
数组、堆栈、队列、树和链表都是容器类。
2.容器类经常与迭代对象(iteratorobject;或简称迭代器,iterator)相关联。
迭代对象返回集合中的下一个项目(或对集合中的下一个项目进行某种操作)。
编写类的迭代器之后,要取得类中的下一个元素很简单,迭代器通常指定为类的友元,以提高性能,使迭代器能通过迭代直接访问private数据。
就像几个人共读的书中可以插好几个标签一样,可以有同时操作几个迭代器的容器类,每个迭代器包含自己的位置信息。
第20章“标准模板库(STL)”中将详细介绍容器和迭代器。
7.10代理类
1.通过隐藏类的实现细节可以防止访问类中的专属信息(包括private数据)和专属程序逻辑。
向客户提供代理类(proxyclass),代理类只能访问类的public接口,这样就可以让客户使用类的服务而不必让客户访问类的实现细节。
8.2运算符重载的基础
1.程序员也可以把运算符和用户自定义的类型一起使用。
尽管C++不允许建立新的运算符,但是允许重载现有的运算符,使它在用于类的对象时具有新类型的含义,这是C++最强大的特点之一。
2.运算符重载最适合用于数学类。
为了与在现实世界中操作这些数学类的方式一致,通常要重载一组运算符。
例如,对于复数类,通常不仅仅要重载运算符+,因为其他算术运算符也经常用于复数。
3.如:
classX{
friendostream&operator<<(ostream&output,constX&x);
friendistream&operator>>(istream&input,X&x);
//必需在public等关键字之前,上述两个运算符一般定义为外部友元函数。
public:
...
private:
...
};
1.在把重载运算符用于类的对象时,重载运算符的功能类似于该运算符作用于内部类型的对象时所完成的功能,避免没有目的地使用重载运算符。
C++中的大部分运算符都可以被重载。
重载不能改变运算符的优先级。
重载不能改变运算符的结合律。
重载不能改变运算符操作数的个数。
重载的一元运算符仍然是一元运算符,重载的二元运算符仍然是二元运算符,C++中的惟一的三元运算符(?
:
)也不能被重载。
运算符&、*、+和-既可以用作一元运算符,也可以用作二元运算符,可以分别把他们重载为一元运算符和二元运算符。
不能创建新的运算符,只有现有的运算符才能被重载。
8.4用作类成员与友元函数的运算符函数
1.运算符函数既可以是成员函数,也可以是非成员函数。
非成员函数通常是友元函数。
成员函数是用this指针隐式地访问类对象的某个参数,非成员函数的调用必须明确地列出该参数。
2.在重载运算符()、[]、->,或者任何赋值运算符时,运算符重载函数必须声明为类的一个成员。
对于其他的运算符,运算符重载函数可以是非成员函数。
3.当运算符函数是一个成员函数时,最左边的操作数(或者只有最左边的操作数)必须是运算符类的一个类对象(或者是对该类对象的引用)。
如果左边的操作数必须是一个不同类的对象,或者是一个内部类型的对象,该运算符函数必须作为一个非成员函数来实现(正如8.5节中分别重载运算符<<和>>作为流插入运算符和流读取运算符一样)。
运算符函数作为非成员函数直接访问该类的private或者protected成员时,该函数必须是一个友元。
4.重载的<<运算符必须有一个类型为ostream&的左操作数(例如表达式cout< 类似地,重载>>运算符必须有一个类型为istream&的左操作数(如表达式cin>>classObject中的cin),所以它也必须是一个非成员函数。 此外,这两个重载的运算符函数都需要访问输出或输入的类对象的private数据成员,因此出于性能考虑,这些重载的运算符函数通常都是类的友元函数。 8.6重载一元运算符 1.类的一元运算符可重载为一个没有参数的非static成员函数或者带有一个参数的非成员函数,参数必须是用户自定义类型的对象或者对该对象的引用。 实现重载运算符的成员函数应为非static,以便访问类的非static数据。 记住,static成员函数只能访问类的static数据成员。 2.重载一元运算符时,把运算符函数用作类的成员而不用作友元函数。 因为友元的使用破坏了类的封装,所以除非绝对必要,否则应尽量避免使用友元函数和友元类。 8.9类型之间的转换 1.但是怎样转换用户自定义类型呢? 编译器不知道怎样实现用户自定义类型和内部类型之间的转换,程序员必须明确地指明如何转换。 这种转换可以用转换构造函数实现,也就是使用单个参数的构造函数,这种函数仅仅把其他类型(包括内部类型)的对象转换为某个特定类的对象。 本章梢后要用一个转换构造函数把正常的char*类型的字符串转换为类Siring的对象。 2.转换运算符(也称为强制类型转换运算符)可以把一种类的对象转换为其他类的对象或内部类型的对象。 这种运算符必须是一个非static成员函数,而不能是友元函数。 8.11重载++与-- 1.要重载既能允许前置又能允许后置的自增运算符,每个重载的运算符函数必须有一个明确的特征以使编译器能确定要使用的++版本。 重载前置++的方法与重载其他前置一元运算符一样。 2.由于编译器必须能区分重载的前置和后置自增运算符函数,所以重载后置自增运算符遇到了一点儿困难。 C++中所采用的方法是,当编译器遇到后置自增表达式: d1++ 编译器就会生成成员函数调用: d1.operator++(0) 该函数的函数原型为: Dateoperator++(int) 严格说来,0是一个伪值,它使运算符函数operator++在用于后置自增操作和前置自增操作时的参数表有所区别。 如果后置自增运算符函数是一个非成员函数,则当编译器遇到表达式: d1++ 编译器就生成函数调用: operator++(d1,0) 该函数的函数原型为: friendDateoperator++(Date&,int); 再重复一遍,编辑器使用参数。 区别后置自增操作和前置自增操作所用到的operator++函数的参数表。 C++大学教程(第9章继承) 1.基类的public成员能够被程序中所有函数访问,private成员只能被基类的成员函数和友元访问。 2.基类的protected成员只能被基类的成员和友元以及派生类的成员和友元访问。 派生类成员简单地使用成员名就可以引用基类的public成员和protected成员。 9.4把基类指针强制转换为派生类指针 1.公有派生类的对象可作为其相应基类的对象处理,这使得一些有意义的操作成为可能。 例如,从某个特定基类派生出来的各种类,尽管这些类的对象彼此之间互不相同,但是仍然能够建立这些对象的链表,只要把这些对象作为基类对象处理就可以了。 然而反过来是不行的,基类的对象不能自动成为派生类的对象。 2.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- cpp 学习 摘要