参考书:c/c++程序设计教程,龚沛增、杨志强 主编
本文主要内容架构如下图:
1 概述
面向对象编程(Object Oriented Programming),面向对象的思想就是要面对现实世界的实体,以对象为基本单位,分析、设计和实现一个系统。
基本概念:
- 对象
现实世界中的对象是各种各样的实体,可以是具体的或抽象的事物。每个对象皆有自己的特征、行为和作用在该对象上的活动。 - 类
许多对象具有相似的性质,执行相同的操作,称之为一类对象。类是创建对象的模板,对象则是类的实例。 - 消息
在面向对象的程序中,程序执行是对象之间传递消息完成的,消息传递一般由 接收消息的对象、所要触发的方法和执行此方法需要的参数组成的。 - 方法
方法是某个对象接受了消息后采取的一系列操作的描述。
2 类和对象
本节内容如下:
2.1 类的定义
类定义的一般形式如下:
class 类名
{
public :
成员函数或数据的说明;
private :
成员函数或数据的说明;
protected :
成员函数或数据的说明;
};
各成员函数的实现;
--类的定义包括说明和实现两部分。如果成员函数在说明部分已经给出定义,则在实现部分可以省略;
--类的成员包含数据成员和函数成员,自身类的对象不能作为自己的成员;
--private,public,protected规定了成员如何被访问,缺省时为private;
--不涉及继承时,protected 与private用法相同;
--类的数据成员不能在声明时进行初始化,只能通过成员函数实现;
--在类体外定义成员函数时,格式为:
类名::函数名(参数)
{
函数实现
};
2.2 对象的定义
定义对象
类名 对象名;
如:
class staff {......};
staff s,*p,s1[5];
//staff为已经定义的类,s是一个对象,p是指向对象的指针,s1为对象数组
对象的访问
- 一般对象成员:
对象名.数据成员名
对象名.函数成员名(参数) - 指针对象成员:
对象指针->数据成员
对象指针->函数成员(参数)
或
(对象指针).数据成员
(对象指针).函数成员(参数)
2.3 对象初始化
构造函数
--与类名相同,不指定函数类型;
--属于成员函数,可以在类体内或体外实现;
--可以重载;
--在创建对象时自动调用,不能在程序中直接调用,多用于初始化;
--用户未定义时,系统会自动生成缺省构造函数;
--用户定义了构造函数,系统不会生成缺省构造函数;
--若定义一个静态对象而没有初始化时,编译器会将所有数据成员初始化为0.析构函数
--在程序结束或使用对象的函数结束前会自动调用,用于释放对象;
--析构函数名是在类名前加~,无参数,不需指定类型;
--属于成员函数,可以在类体内或体外定义;
--不能重载;
--可以由系统自动调用,也可以在程序中调用;
--用户未定义时,系统会自动生成空的缺省析构函数。拷贝初始化构造函数
--用一个已知的对象来初始化一个被创建的同类对象;
--函数名与类名相同,只有一个参数,且该参数是对同类对象的引用;
--如果用户没有定义拷贝初始化构造函数,则系统会自动生成,并将参数对象的全部数据值拷贝给正在创建的对象。
2.4 常对象和常成员
声明常对象:
const 类名 对象名;
常对象中所有数据成员的值只能在构造函数中初始化,不能被修改。
常函数成员
声明常函数成员:
类型说明符 函数名(参数) const
{......};
--只有常成员函数可以操作常对象;
--修改数据对象的函数不能声明为常函数;
常数据成员
声明常数据成员:
const 数据类型 变量名;
--常数据成员不能被任何函数改动;
--构造函数只能通过初始化列表对其初始化,如:
class circle
{
private:
double x,y;
const double r;
public:
circle(double x1, double y1,double r1):r(re)
{
x=x1;y=y1;
}
}
2.5 静态成员
希望一个成员能供所有对象共享时,可以设为静态成员。
静态数据成员
--静态数据成员声明时在前面加static;
--静态数据成员是类的成员,不是对象的成员;
--初始化在类体外进行,不加static和访问权限控制符。
//初始化格式:
数据类型 类名::静态数据成员=值;
//引用格式:
类名:静态数据成员名
静态函数成员
--声明时在前面加static;
--静态成员函数中可以直接引用静态数据成员,对于非静态数据成员,要通过对象引用;
--除了可以像其他成员函数一样引用,还可以如下引用:
类名::成员函数名(参数)
2.6 友元函数
友元函数提供了一种非成员函数访问类的私有成员的方法,在一定情况下可以提高程序的执行效率,但破坏了类的封装和隐藏性。
--友元函数不是成员函数,但要在类体内说明;
--友元函数说明时,要在前面加friend,实现时不许加friend;
--友元函数可以通过对象的方式访问类中的私有成员。
3 派生和继承
继承是软件可重用性的一种形式,新类通过这种方式,从现有的类中吸收其属性和行为,并对其覆盖和改写,产生新类所需要的功能。
本节内容如下:
3.1 派生
通过继承机制,可以应用现有类来定义新类。已经存在的类称为基类或父类,由已存在的类派生的新类叫派生类或子类。
派生类拥有基类的成员,也可以定义新成员。
3.2 继承
一个派生类可以由一个基类派生,称为单继承;也可以由多个基类派生,称为多继承。
单继承
-
派生类的定义
class 派生类名:继承方式 基类名 { 派生类新成员定义 };
派生类的继承方式
不同的继承方式中,派生类对基类成员的访问权限不同,如下:
基类 | 私有成员 | 公有成员 | 保护成员 |
---|---|---|---|
私有派生 | 不可访问 | 私有成员 | 私有成员 |
公有派生 | 不可访问 | 公有成员 | 保护成员 |
保护派生 | 不可访问 | 保护成员 | 保护成员 |
--不论何种继承方式,基类的私有成员均不可被派生类及其成员函数访问;
--私有继承时,基类的公有成员和保护成员均成为派生类的私有成员;
--公有继承时,基类的公有成员和保护成员类型不变被继承到派生类中;
--保护继承时,基类的公有成员和保护成员均成为基类的保护成员;
--若基类的公用成员访问了基类的私有成员,则在派生类中不能使用,需要通过基类的方式调用。
-
派生类的构造函数
定义派生类的构造函数时,除了对自己的数据成员初始化,还需调用基类的构造函数。如果派生类中的成员含有基类对象,则还应该对基类对象进行初始化,例如:派生类构造函数(初始化总参数表):基类构造函数(参数表1),基类对象名(参数表2) { 派生类中数据成员初始化 }
--调用顺序:基类构造函数——基类对象构造函数——派生类构造函数;
--基类中有缺省的构造函数或未定义时,派生类构造函数可以省略调用基类构造函数;
--若基类只包含有参数的构造函数,则在派生类中一定要调用。
#include
using namespace std ;
class circle
{
private:
double x,y,r;
public:
void print() //const
{
cout<<"圆心:"<
运行结果:
-
派生类析构函数
格式:~派生类名() {......};
系统先执行派生类的析构函数,再执行基类的析构函数。
4 多态性
多态性是指同一个操作对于不同的对象会产生不同的反应。函数重载和运算符重载属于静态重载,建立在虚函数上的多态性属于动态重载。
本节内容如下:
4.1 函数重载
函数重载是指同一个函数名有不同的定义,定义重载函数时,要求参数至少有一个类型不同,或者个数不同,对返回值无要求。
4.2 运算符重载
运算符重载原则
遵循函数重载的原则;
不能改变运算符的优先级和结合性,不改变其语法结构。-
重载为类的成员函数
定义形式:
类名 operetor 运算符(参数表)
调用形式:
对象1 运算符 对象2
例如(程序待完善):class Str { private: char *s; ...... public: Str operator + (Str s1) //将+号重载为字符串拼接 { strcat(s, s1.s); Str result(s); return result; } }; void main() { Str s1,s2,s3; s3=s1+s2; }
重载为友元函数
(待补充)this指针
this是一个无需特殊定义的指针,它隐含于每一个类的成员函数中,指向正在被某个成员函数操作的对象。
如果某个对象调用的成员函数,则编译程序首先将这个对象的地址赋给this指针,然后调用成员函数。
4.3 虚函数
虚函数是一种非静态的成员函数,反映了基类和派生类之间的特殊关系,定义形式:
virtual 类型说明符 函数名 (参数表)
如果在基类中,某个函数被声明为虚函数,则在派生类中,该成员函数可能有其他的实现方法。
例子:
class Animal
{
public:
void character()
{
cout<<"动物特征:不同"<
运行结果:
在例程中,函数f的参数为基类指针,主函数调用时传入的为派生类的地址,此时,实际操作的是基类的成员函数,而对于虚函数,则会根据派生类对象的地址执行派生类中的函数。
虚函数的使用说明:
--派生类中的虚函数应与基类中的虚函数有相同的函数名、参数类型及个数;
--派生类的虚函数可以不显示声明;
--只有虚函数操作的是对象的指针或对象的引用时,对该虚函数的调用采取的才是动态联编。
4.4 抽象类
含有纯虚函数的类称为抽象类。
纯虚函数是指在基类中定义为空的虚函数。
抽象类的性质:
--只能用作其他类的基类,不能建立其对象;
--不能用作参数类型和函数返回值类型;
--可以说明指向抽象类指针引用,此指针可以指向其派生类。