C++作为一门兼具面向对象和面向过程双重特点的编程语言,自然具备面向对象编程的特点。这些特点包括类(class)、对象(object)、继承(inheritance)、封装(encapsulation)、抽象(abstract)和多态(polymorphism),本文详细介绍C++类的若干特点。
- C++对象和引用中的公共成员(public attributes,包括变量和函数)可以用类名加点的方式获取,C++指针所对应的类中的成员可以用成员选取操作符(->)进行获取。(C++11 Chap 9.1 p.g.257)
- 由于一个类通常只能被定义一次,因此使用诸如:
#ifndef XXX_H
#define XXX_H
/*此处为类XXX的代码*/
#endif
的预处理指令可以有效防止类被重复定义。(C++11 Chap 9.2 p.g.258)
- setfill函数是一个粘性操作符。(C++11 Chap 9.2 p.g.261)
- 理论上来说,类的成员函数默认情况下会被隐式定义为inline函数,以加快编译速度。(C++11 Chap 9.2 p.g.261)
- C++异常处理机制的头文件是<stdexcept>,通过what函数可以获得具体的异常信息。异常处理简明用法示例如下(C++11 Chap 9.2 p.g.263):
try{//...try语句块代码}
catch( except &e){ cout << e.what() << endl; }
-
类中的函数按照用途大致可以分为三种:
- 存取函数(access functions):即常见的get和set函数,用于读取类中的变量。
- 判定函数(predicate functions):返回值为布尔值,用于判定类中某个成员的特定属性,如isEmpty()。
- 辅助函数(utility functions, helper functions 或 auxiliary functions):一般为类内的私有函数,供该类的某个公有函数调用,如很多涉及递归的函数。(C++11 Chap 9.4 p.g.265)
-
C++类中的不同构造函数之间可以相互调用,此时去调用其他构造函数的构造函数称为委托构造函数(delegating constructor)。(C++11 Chap 9.5 p.g.271)。使用示例如下:
//假设Time类中同时含有如下两个构造函数:
Time(int);
Time(int, int):
//则可以有如下用法:
Time::Time( int hour ) : Time(hour, 0, 0){}
-
析构函数以波浪符(~)开头。波浪符是二进制中取反的意思,寓意为析构的过程为构造的相反过程。(C++11 Chap 9.6 p.g.272)
-
C++类的析构顺序,详见博文:https://my.oschina.net/SamYjy/blog/828146
-
应当避免返回类中私有成员所对应的引用,详细情况见博文:https://my.oschina.net/SamYjy/blog/828779
-
C++中可以使用等于符号(=)将对象进行赋值,此操作被成为对象赋值(或成员赋值,memberwise assignment 或 copy assignment)。(C++11 Chap 9.9 p.g.279)
-
C++常量对象若干注意点(C++11 Chap 9.10 p.g.281 - 283):
- 若一个对象不可更改,任何试图更改该对象的操作都将导致编译报错,则可以在该对象的引用前面加上关键字const,例如:``` const Time noon(12, 0, 0)
- 将变量定义为const有利于提高编译速度,因为编译器能对于常量进行一些变量不具备的优化操作。
- C++禁止调用常量对象中的非常量函数。
- 调用常量对象的构造函数或析构函数导致编译错误,常量对象的常量态是指从其被构造开始到被析构为止存在的时间。
- 通过常量对象中的构造函数在初始化时即调用其中的非常量函数是允许的。
- 面向对象设计中的复合(composition)概念:一个类中含有对另一个类的对象的调用,两个类构成has-a关系。(C++11 Chap 9.11 p.g.283)
- 类中成员的构造顺序取决于它们在类的定义文件中被定义的顺序,而不是取决于构造函数参数列表中的调用顺序。(C++11 Chap 9.11 p.g.283)
- 静态类使得每个调用此对象的类可以共用一份该类的成员数据。通常情况下,在调用的时候(计数的)成员变量会被增加,而在析构的时候会被减少。C++11之前,静态常量中的int型和枚举型可以在类中定义,其他的变量都必须在命名空间或全局中定义。此外,如果在调用析构函数前程序终止(如调用了exit或abort函数),则析构函数失去效力。(C++11 Chap 9.7 p.g.273)
- 一个类的私有或受保护变量(无论静态与否)通常都是通过该类的共有类或者友元函数进行读取的。如果需要在类不存在的情况下调用该类的公有静态变量,可以通过类名::成员名的形式。使用静态变量在编译方面可以节约时间和空间。(C++11 Chap 9.14 p.g.298)
- 静态成员不含有this指针,因为静态变量和静态函数是不依赖于任何类存在的。this指针必须指向一个类的具体对象。当静态成员被调用时,内存中可能事实上已经并不存在任何对象。(C++11 Chap 9.13 p.g.291 / Chap 9.14 p.g.301)。关于this指针的更多资料,可以参考博文:https://my.oschina.net/SamYjy/blog/828757
- 将一个静态函数定义为常量会导致编译错误。因为const表示此函数不得修改此类的参数,而static表示此函数脱离此类存在,是相互矛盾的定义。(Chap 9.14 p.g.301)
关于typedef(Chap 13.2 p.g.418):typedef关键字并没有创建新的数据类型,而只是创建了新的数据类型名称(描述既有数据类型的特定名称)。例如:
//CardPtr的代表Card *类型变量 typedef Card * CardPtr;
参考资料:
1. Paul Deitel & Harvey Deitel, C++11程序设计(英文版)(第2版),本文中C++11括号所表示的资料