- 静态成员
可以定义类的静态成员,而不是定义一个可普遍访问的全局对象,就能够实现同类的多个对象之间的数据共享。静态数据成员在内存中只占一份空间,而不是每个对象都分别为它分配一份空间,静态数据成员的值在所有对象中都是一样的。
在未建立类对象时也已经为静态数据成员分配空间,因此可以在未建立类对象时访问静态成员。
静态数据成员不通过类构造函数进行初始化,而是在定义时进行初始化。静态数据成员必须在类外部定义一次,仅有一次。
静态成员函数和静态数据成员一样,是类的一部分,而不是对象的一部分。
静态成员函数和非静态成员函数的区别:
非静态成员函数有this指针,而静态成员函数没有this指针,因此静态成员函数不能访问本类中的非静态成员,作用是为了访问静态数据成员。 - 友元
C++提供了友元机制,允许一个类将其非公有成员的访问权限授予指定的函数或类。友元的生命以关键字friend开始,它只能出现在类定义的内部。
因此,现在访问类的非公有成员可以有两个用户:类成员和友元。
面向对象程序设计的一个基本原则就是封装性和信息隐蔽,而友元却可以访问其他类的私有成员,突破了封装原则。友元的使用有助于数据共享,能提高程序的效率,但是也不要滥用。 - 泛型编程
面向过程(PO)是通过将代码段封装在一个函数中,通过函数调用来实现目标代码的重用。
面向对象是通过类的继承来实现对象目标代码的重用。
泛型是一种允许一个数据取不同类型的技术,泛型算法是与操作对象的数据类型独立的算法。泛型算法建立在各种抽象化基础之上。利用参数化模板来达到数据类型的抽象化,利用容器和迭代器来达到数据结构的抽象化,利用分配器和适配器来达到存储分配和界面接口的抽象化。 - 数据封装
C++通过类实现数据封装,即通过指定各成员的访问权限来实现。 - 继承和派生
在C++中,继承就是在一个已存在的类的基础上建立一个新的类。在一个派生类中,其成员由两部分构成:一部分是从基类继承得到的,另一部分是自己定义的新成员。
友元关系不能继承。一方面,基类的友元对派生类的成员没有特殊的访问权限,另一方面,如果基类被授予友元关系,则只有基类具有特殊的访问权限,该基类的派生类不能访问授予友元关系的类。
只有基类类成员和友元可以访问基类的private部分,派生类不能访问基类的私有成员。但是若声明为protected,仍然不能被类用户访问,但是可被派生类访问。 - 派生类的构造和析构函数
在定义派生类时,派生类并没有把基类的构造函数和析构函数继承下来。因此,对继承的基类成员的初始化工作要由派生类的构造函数来承担,同时基类的析构函数也需要由派生类的析构函数来调用。
如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类数据成员的多份同名成员。所以C++提供了虚基类机制,使得在继承间接共同基类时只保留一份成员。 - 多态性和虚函数
多态是指同样的消息被不同类型的对象接收时导致不同的行为。所谓消息是指对类成员函数的调用,不同的行为是指不同的实现,也就是调用了不同的函数。
多态的分类:
- 重载多态
重载分为函数重载和运算符重载。重定义已有的函数称为函数重载。重定义已有运算符的语义为运算符重载。 - 强制多态
强制类型转换 - 参数化多态
将类型作为函数或类的参数,避免为各种不同的数据类型编写不同的函数或类,提高了程序设计的灵活性。
模板是C++实现参数化多态性的工具,分为函数模板和类模板。 - 包含多态
C++中采用虚函数实现包含多态。至少含有一个虚函数的类称为多态类。
- 赋值兼容性规则
赋值兼容性规则是指在需要基类对象的任何地方,都可以使用公有派生类对象来替代。即子类可以赋值给基类。
赋值兼容规则是C++多态性的重要基础之一。 - 联编binding
联编又称绑定,就是将模块或函数合并在一起生成可执行代码的处理过程,同时对每个模块或者函数分配内存地址,并且对外部访问也分配正确的内存地址。
静态联编:在编译阶段就将函数实现和函数调用绑定起来
动态联编:在程序运行的时候才进行函数实现和函数调用的绑定,运用虚函数 - 虚函数
如果派生类没有改写基类的虚函数,则函数指针调用基类的虚函数。如果派生类改写了基类的心虚函数,编译器将重新为派生类的虚函数建立地址,函数指针会调用改写以后的虚函数。
利用虚函数,可以在基类和派生类中使用相同的函数名定义函数的不同实现。当用基类指针或引用对虚函数进行访问时,系统将根据运行时指针或引用所指向的实际对象来自动确定调用对象所在类的虚函数版本。 - 虚析构函数
当基类的析构函数声明为虚函数时,无论指针指的是同一类族中的哪一个类对象,系统总会采用动态联编,调用正确的析构函数,对该对象进行清理。
C++支持虚析构函数,但不支持虚构造函数,即构造函数不能声明为虚函数。这是因为在执行构造函数时,类对象还未完成建立过程,当然谈不上虚函数与类对象的绑定。 - 抽象类
纯虚函数=0没有函数体,便于派生类根据需要对它进行定义。
包含纯虚函数的类称为抽象类。一个抽象类只能作为基类来派生新类,而不能定义对象。抽象类的主要作用是声明一族派生类的共同接口,而接口的完整实现,即纯虚函数的函数体需要由派生类自己定义,使它们能够更有效的发挥多态特性。 - 运算符重载
C++不允许创造新的运算符,不过它允许重载大部分现有运算符,赋予其另一种功能,以适应不同的类型。