C++要点总结
1.内联成员函数
1)隐式声明:将成员函数直接定义在类的内部 2)显式声明:inline标示
2)在类中,使用inline定义内联函数时,必须将类的声明和内联成员函数的定义都放在同一个文件中,否则编译时无法进行代码置换。
2.同类对象赋值
1)对象赋值语句进行对象赋值时,两个对象的类型必须相同
2)数据成员占存储空间,成员函数占相同的函数代码段
3)类中存在指针时,使用默认赋值运算函数赋值,可能错误
3.构造函数
1)跟普通成员函数一样,当构造函数直接定义在类中时,作为内联函数处理
2)一般声明为公有成员,但不能显式调用,定义对象时自动调用,且只执行一次
4.成员初始化列表
1)C++中,引用类型和const修饰的成员不允许在构造函数中用赋值语句直接赋值
2)类成员按照在类中被声明的顺序初始化,与在初始化列表中列出的顺序无关
5.析构函数
1)析构函数没有参数、返回值,且不能重载
2)撤销对象时,编译系统自动调用析构函数
6.默认构造函数
1)当一个类定义了一个构造函数,系统不再提供默认构造函数
7.重载构造函数
1)一个类中,当无参数的构造函数和带默认参数的构造函数重载时,可能产生二义性
8.拷贝构造函数
1)拷贝构造函数只有一个参数,并且是同类对象的引用
2)每个类都有一个拷贝构造函数
3)调用拷贝构造函数三种情况:(1)当用类的一个对象去初始化该类的另一个对象时(2)当函数形参是类的对象(3)当函数的返回值是对象
9.浅拷贝和深拷贝
1)默认的拷贝构造函数是浅拷贝。有指针类型时,只是让指针指向同一块内存,没有申请新的内存
2)默认的拷贝构造函数处理带指针类型数据时,当调用析构函数时可能出现错误
10.静态数据成员
1)静态数据成员初始化应在定义对象之前,类外单独进行。一般在main()之前、类声明之后。如:int Student::count = 0
2)静态数据成员属于类
3)静态数据成员跟静态变量一样,在编译时创建并初始化
11.静态成员函数
1)静态成员函数的作用是为了处理静态数据成员。如确实需要,静态成员函数只能通过对象名访问该对象的非静态成员
2)静态成员函数与非静态成员函数的重要区别是:非静态成员函数有this指针,静态成员函数没有this指针
3)私有静态成员函数不能被类外部的函数和对象访问
4)静态成员函数可以在建立任何对象之前调用,以处理静态数据成员
5)编译系统将静态成员函数限定为内部连接
6)静态成员函数是类的一部分,而不是对象的一部分,可以用类名::或对象调用共有静态成员函数
12.非成员函数声明为友元函数
1)友元函数既可以是不属于任何类的非成员函数,也可以是另一个类的成员函数
2)因为友元函数不是类的成员,所以不能直接访问对象的数据成员,也不能通过this指针访问对象的数据成员,必须通过作为入口参数传递进来的对象名 (指针、引用)来访问该对象的数据成员
3)友元函数提供了不同类的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制
13.成员函数声明为友元函数,称为友元成员函数
1)一个类的成员函数作为另一个类的友元函数时,必须先定义这个类
2)提前引用声明
14.友元类
1)当一个类被说明为另一个类的友元类时,它所有的成员函数都成为另一个类的友元函数
2)友元关系没有交换性和传递性
15.类的组合
1)当调用构造函数时,按各对象成员在类声明中的顺序依次调用他们的构造函数,再执行类的构造函数体
2)调用顺序跟在初始化列表中的顺序无关。析构函数跟构造函数顺序相反。
16.常引用与常对象
1)常引用往往用来作为函数的形参,这样的参数称为常参数。
2)C++不允许更改常对象的数据成员,C++不允许常对象调用普通的成员函数
17.常对象成员
1)类中说明的常数据成员,构造函数只能通过初始化列表对它初始化
2)常成员函数在声明函数和定义函数时都要有关键字const
3)关键字const可以被用于对重载函数区分
4)常成员函数可以访问常数据成员,也可以访问普通数据成员,但都不能改变
5)普通成员函数可以访问和改变普通数据成员,可以访问常数据成员但不能改变
6)常对象只能调用它的常成员函数,常成员函数是常对象唯一对外接口
7)常成员函数不能更新对象的数据成员,也不能调用该类普通成员函数
18.基类成员在派生类中的访问属性
1)派生类可以继承基类中除了构造函数与析构函数之外的成员
2)基类中的私有成员无论哪种继承,在派生类中都不可直接访问
3)其他在派生类中的访问属性为基类中的访问属性与继承方式中较低公开性的那个
19.派生类构造和析构函数的调用顺序
1)当创建派生类对象时,先调用基类的构造函数,随后调用派生类构造函数
2)当含有子对象时,先调用基类构造函数,然后调用子对象构造函数,最后调用派生类构造函数体,撤销对象时,析构跟构造函数顺序相反
3)如果派生类的基类也是一个派生类,每个派生类只负责其直接基类的数据成员初始化
20.同名成员
1)在没有虚函数时,如果在派生类中定义与基类成员同名的成员,则称派生类成员覆盖了基类的同名成员,在派生类中使用该成员意味着访问重新声明的成 员。用::可以访问到基类的同名成员。
21.访问声明
1)访问声明可个别调整基类的某些成员在派生类中的访问属性,使在派生类中保持原来的访问属性
2)访问声明只能是基类名::成员名的形式,不可带类型和参数,如:A::disp,A::a
3)访问声明不能改变成员在基类中的访问属性,对基类的私有成员不能使用访问声明
4)对于基类中的重载函数名,访问声明对基类所有同名函数起作用
22.多继承
1)多继承中的构造函数的调用顺序与初始化列表中的顺序无关,只与声明继承方式时顺序有关
23.虚基类
1)为了解决多继承中的二义性
2)如果在虚基类中定义有带形参的构造函数,并且没有定义默认形式的构造函数,则整个继承结构中,所有直接或间接的派生类都必须在构造函数成员初始 化列表中列出对虚基类构造函数的调用
3)建立一个对象时,如果这个对象中含有从虚基类继承来的成员,则虚基类的成员是由最远派生类的构造函数通过调用虚基类的构造函数进行初始化的,该 派生类的其他基类对虚基类构造函数的调用都自动被忽略。
4)同一层次中同时包含虚基类和非虚基类,应先调用虚基类的构造函数,再调用非虚基类的构造函数,最后调用派生类构造函数。
5)对于多个虚基类,构造函数的执行顺序仍然是先左后右,自上而下。
6)对于非虚基类,构造函数的执行顺序仍是先左后右,自上而下。
7)若虚基类由非虚基类派生而来,则仍然先调用基类构造函数,再调用派生类的构造函数。
24.赋值兼容
1)共有派生类是基类真正的子类,它完整地继承了基类的功能。要求公有派生。
2)在基类的对象可以使用的地方,都可以用派生类的对象来替代,但只能使用从基类继承来的成员
3)派生类对象可以赋值给基类对象
4)派生类对象可以初始化基类对象的引用
5)派生类对象的地址可以赋给指向基类对象的指针
6)如果函数的形参是基类对象或基类对象的引用,在调用函数时可以用派生类对象作为实参
25.多态性
1)C++中,编译时多态性主要通过函数重载和运算符重载实现,运行时多态性主要是通过虚函数实现的
2)C++规定:基类的对象指针可以指向它公有派生的对象,但是当其指向公有派生类对象时,它只能访问派生类从基类继承来的成员,不能访问公有派生类 中定义的成员
3)虚函数是基类中的成员函数,加上关键字virtual,并在派生类中被重载
4)最好在对派生类的虚函数进行重新定义时也加上关键字virtual
5)一个虚函数无论被公有继承多少次,它仍然保持其虚函数的特性
6)虚函数必须是其所在类的成员函数,而不能是友元函数,也不能是静态成员函数,因为虚函数调用要靠特定的对象来决定激活哪个函数
7)内联函数不能是虚函数,因为内联函数是不能在运行中动态确定其位置的。即使虚函数在类的内部定义,编译时仍将其看作是非内联的
8)构造函数不能是虚函数,但是析构函数可以是虚函数,并且通常说明为虚函数
9)虽然派生类的析构函数与基类的析构函数名字不相同,但是如果将基类的析构函数定义为虚函数,由该基类所派生的所有派生类的析构函数也都自动成为 虚函数
10)在派生类中重新定义虚函数时,如果仅仅返回类型不同,其余均相同,系统会给出错误信息;若仅仅函数名相同,而参数的个数、类型或顺序不同,系 统将它作为普通的函数重载,丢失虚函数特性
26.纯虚函数
1)考虑到派生类的需要,在基类中预留一个函数名,具体功能由派生类定义
27.抽象类
1)如果一个类至少有一个纯虚函数,那么这个类称为抽象类
2)抽象类只能作为其他类的基类使用,不能建立对象
3)不能从具体类中派生出抽象类
4)抽象类不能作为函数的参数类型、函数返回类型、显示转换的类型
5)可以声明指向抽象类的指针或引用
6)如果派生类中没有定义纯虚函数的实现,而派生类只是继承基类的纯虚函数,则这个派生类仍然是一个抽象类
28.函数模板
1)在函数模板中允许使用多哥类型参数
2)在template语句与函数模板定义语句之间不允许插入别的语句
3)同一般函数一样,函数模板也可以重载
4)函数模板与同名的非模板函数可以重载。调用顺序是首先找一个参数完全匹配的非模板函数,找到就调用,否则寻找函数模板,将其实例化,产生模板函 数
29.类模板
1)在类模板外定义成员函数时,若成员函数中有类型参数存在,则a.需要在成员函数定义前进行模板声明 b.在成员函数名前加上“类名<类型参数>::”
2)每个类模板定义之前,都需要在前面加上模板声明template <typename Type>,使用类模板时,必须在类模板名字后面加上<类型参数> Stack<Type>
3)模板类可以有多个类型参数