一、类与对象
1. 成员函数
定义
- 在类定义内部定义(默认 inline)
- 在类的外部使用范围解析运算符 :: 来定义
2. 类访问修饰符
- public:数据和函数在类的外部是可访问的,可以不使用任何成员函数来访问工有数据
- private:
- 数据和函数在类的外部是不可访问的
- 只有类和友元函数可以访问私有成员,不能被派生类访问
- (PS:没有使用任何访问修饰符,类的成员将被假定为私有成员)
- protected:数据和函数在类的外部是不可访问的,在派生类(即子类)中是可访问的
3. 构造函数与析构函数
构造函数的名称与类的名称完全相同,并且不会返回任何类型,也不会返回 void
可以使用初始化列表来初始化字段
析构函数的名称与类的名称完全相同,只是在前面加了 ~,不会返回任何值,也不能带有任何参数
析构函数完成对象被删除前的一些清理工作
4. 拷贝构造函数
拷贝构造函数是一种特殊的构造函数,使用同一类中之前创建的对象来初始化新创建的对象
拷贝造函数的名称与类的名称完全相同,并且不会返回任何类型,其参数是同类对象的引用
5. 友元函数
类的友元函数『并不是成员函数』,是定义在类外部,但有权访问类的所有私有和保护成员
在类定义中该函数原型前使用关键字 friend
6. 内联函数
如果一个函数是内联的,那么在编译时,编译器会把出现内联函数调用表达式的地方,用内联函数的函数体进行替换
在函数名前面放置关键字 inline
内联函数是为了解决程序中函数调用的效率问题,就是空间换时间,所以内联函数一般都是小函数
注意:
在内联函数内不允许使用循环语句和开关语句
内联函数的定义必须出现在内联函数第一次调用之前
在类内部定义的函数会默认声明为inline函数,所有不用显示地去声明inline
7. this 指针
每一个对象都能通过 this 指针来访问自己的地址
this指针是所有成员函数的隐含参数,在成员函数内部,this指针可以用来指向目前调用的对象
友元函数没有 this 指针,因为不是类的成员
8. 静态成员
静态成员在类的所有对象中是共享的
1) 静态成员数据
如果不存在初始化语句,在创建第一个对象时,所有的静态数据都会被初始化为零
不能把静态数据的初始化放在类的定义中,而是在类的外部使用范围解析运算符 :: 来进行初始化
2) 静态成员函数
静态成员函与类的对象是独立的,在类对象不存在的情况下也能被调用
『静态成员函数只能访问静态成员数据、其他静态成员函数和类外部的其他函数,且没有 this 指针』
这个例子挺好的:http://www.runoob.com/cplusplus/cpp-static-members.html
二、继承
1. 继承
一个类可以派生自多个类,即一个(子类/派生类)可以有多个(父类/基类)
1 | class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,… |
2. 继承方式不同,基类成员在派生类中的访问属性不同
三种继承方式,使得基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:
- public 继承:public, protected, private
- protected 继承:protected, protected, private
- private 继承:private, private, private
3. 派生类中构造函数和析构函数的调用
- 创建子类时先调用父类的构造函数然后再调用自己的构造函数
- 子类先调用自身的析构函数再调用父类的析构函数
1)构造函数不能是虚函数
从继承来讲,总是要先构造父类对象,然后才能是子类对象
虚函数的作用在于通过父类的指针或者引用,来调用子类的成员函数,而构造函数是在创建对象时自动调用,不可能通过父类的指针或者引用去调用,因此也就规定构造函数不能是虚函数
2)通常将基类的析构函数定义为虚函数的原因
- 当派生类指针指向派生类时,先调用派生类的析构函数再调用基类的析构函数
- 当基类指针指向派生类对象实现多态时,在析构时为了防止只析构基类而不析构派生类,一般会将基类析构函数定义为虚基类,这样就会先调用派生类析构函数,再调用基类析构函数
三、函数重载和运算符重载
重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义不同
重载的运算符其实是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符构成
并且重载运算符这个特殊函数是有返回类型和参数列表
注意:
- 运算重载符不可以改变操作数的个数
- 运算重载符不可以改变优先级
- 运算重载符不可以改变结合性
- 有些运算符是不可重载的
四、多态
多态发生的条件:多态只在『基类指针或引用指向派生类对象』的时候才发生,并且基类函数是虚函数
1. 基类、派生类指针指向的对象
- 基类指针指向派生类对象,是安全的
- 派生类指针指向基类对象,会产生编译错误
- 派生类指针指向派生类对象,调用的是派生类的成员
2. 虚函数
在基类中使用关键字 virtual 声明的函数,派生类中重新定义基类中定义的虚函数
虚函数使用条件是当『基类指针指向派生类对象』时,会告诉编译器不要静态链接到基类的虚函数,而是根据所调用的对象类型动态链接到派生类中的成员函数
基类的指针指向派生类的对象,当调用同名的成员函数时:
- 如果在基类中成员函数为虚函数,那么基类指针调用的就是派生类的同名函数
- 如果基类中成员函数为非虚函数,则调用的是基类的成员函数
3. 纯虚函数
在基类中不给虚函数提供有意义的定义实现,纯虚函数的意义在于定义抽象类
声明是在普通的虚函数后面加上”=0” virtual int area() = 0;
五、抽象类
抽象类:如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类
抽象类不能被用于实例化对象