590 likes | 721 Views
类与对象. 内容. 类与对象的含义 类的定义 ( 成员变量和成员函数 )? 类成员的访问控制 ? 类作用域 特殊的类成员 ( 常量、静态、对象) 构造函数和析构函数 友元. 对象. 对象由属性和操作构成 属性:状态,特征,组成成员, 操作:修改属性,访问属性,执行命令 类是具有相似特征的对象的抽象 文件类 所有具体文件对象的抽象 书 类 所有具体书对象的抽象 学生类 所有具体学生对象的抽象. 类与对象. 类是抽象的,对象是具体的 类是类型,对象是变量 类是模型,对象是实例. 类的定义. class File { private:
E N D
内容 • 类与对象的含义 • 类的定义(成员变量和成员函数)? • 类成员的访问控制? • 类作用域 • 特殊的类成员(常量、静态、对象) • 构造函数和析构函数 • 友元
对象 • 对象由属性和操作构成 • 属性:状态,特征,组成成员, • 操作:修改属性,访问属性,执行命令 • 类是具有相似特征的对象的抽象 • 文件类所有具体文件对象的抽象 • 书 类所有具体书对象的抽象 • 学生类所有具体学生对象的抽象
类与对象 • 类是抽象的,对象是具体的 • 类是类型,对象是变量 • 类是模型,对象是实例
类的定义 class File { private: char file_name[100]; int length; Date modify_date; char * content; public: bool copy(File & target); bool rename(char * new_name); bool print(); }; 属性 操作
类的函数成员定义 //修改文件名为new_name bool File::rename(char * new_name) { strcpy( file_name, new_name); }
对象的创建 • 直接创建变量 • File f1, f2; • 动态创建变量 • File *pFile; • pFile = new File; • ...... • delete pFile;
访问成员变量 圆点操作符 • strcpy( f1.file_name , "oopd.dat"); • f1.length += 10; • cout << pFile->contents; 指针操作符
访问成员函数 f1.copy(f2); f1.rename("classA"); pFile->print(); pFile->rename("newname"); f1.copy(*pFile);
封装在类中的实现 • 类的成员的访问控制 • 公有(public) --公开 • 保护(protected) --适当公开 • 私有 (private) --不公开
访问控制的基本原则 • 类的数据成员一般不公开 • private, protected • 表示接口的函数成员一般公开 • public • 与实现细节有关的函数成员不公开 • private, protected
类作用域 • 类作用域包括: • 类的定义体 • 类的所有非内联成员函数的定义体 • 类成员的作用域是类作用域 • 类对象的作用域遵循一般变量的作用域规则(文件作用域、局部作用域)
对象的作用域 File my_file; void main() { File your_file; my_file.copy(your_file); your_file.rename("newname"); } ......
域 操作符 :: • ::identifier 文件域标识符 • classname::identifier 类域标识符 • identifier 当前(或外层)域标识符 bool File::rename(char file_name) { strcpy(File::file_name, file_name); }
特殊的类成员 • 常量成员 • 对象一旦定义,就不能更改该成员 • 静态成员 • 由该类的所有对象共享 • 对象成员 • 一个类的对象作为另一个类的对象的组成部分
特殊的类成员--常量成员 class Polygon { const int edge_num; //边的个数 Point point[100]; //各个顶点位置 //...... public: int GetEdgeNumber(); void SetEdgeNumber(int num) { edge_num = num; } ...... };
特殊的类成员--静态成员 class File { private: static int file_number ; ...... public: static int get_file_number() { return file_number;} };
静态成员的用途 • 记录对象个数 • 一般在构造函数中增加,析构函数中递减 • 所有对象共享资源 • 内存、文件、数据库、打印机
特殊的类成员--对象成员 class Date { int year, month, day; public: SetDate(int y, int m, int d); GetDate(char * date); }; class People { Date birthday; char name[20]; ...... };
对象成员的意义 • 对象之间的组成关系是对象之间存在的重要关系,它反映了自然界中存在的全局与局部、总体和部分的关系,是面向对象思想的重要组成部分。
对象成员的使用 void People::SetBirthday(int y, int m, int d) { birthday.SetDate(y , m , d); } People mary; mary.SetBirthday(1999,1,2); mary.birthday.year = 1997; //如果year是公有成员
对象的初始化 • 类对象的成员不能在类定义时初始化 class File { private: int length = 0; char file_name[] = "test.cpp"; ...... }; 类定义时并不分配空间
类成员的初始化 • 类成员的初始化在对象创建时进行 File my_file("test.cpp"); File your_file("noname.cpp"); • 实现: 构造函数
构造函数 class File { private: int length; char file_name[100]; ...... public: File(char name[]); //构造函数 };
构造函数的实现 File::File(char name[]) { strcpy(file_name, name); length = 0; } //......
构造函数的调用时间 • 在对象建立时由系统自动调用 File myFile("myfile.cpp"); File *pFile = new File("yourfile.cpp");
构造函数的含义 • 直接含义: • 对象建立时初始化对象的数据成员 • 间接含义: • 构造一个具有意义的正确的对象
构造函数的特点 • 函数名和类名相同 • 无返回值 • 由系统自动调用 • 必须是公有(public)成员 • 可以重载 • 可以初始化常量数据成员
构造函数的重载 class Polygon { int edge_num; //边的个数 char line_color; //线的颜色 Point point[100]; //各个顶点位置 //...... public: Polygon(); //默认构造函数 Polygon(int edgeNum ); Polygon(char color , int edgeNum = 3 ); };
默认构造函数 Polygon::Polygon() { edge_num = 3; color = 0 ; //默认颜色 for(int i = 0 ; i < edge_num; i++) point[i].x = point[i].y = 0; }
带参数的构造函数 Polygon::Polygon(int edgeNum) { edge_num = edgeNum; color = 0 ; //默认颜色 for(int i = 0 ; i < edge_num; i++) point[i].x = point[i].y = 0; }
常量成员的初始化 class Polygon { const int edge_num; //边的个数 //...... public: Polygon(); //默认构造函数 Polygon(int edgeNum ); Polygon(char color , int edgeNum = 3 ); };
成员初始化 参数表 Polygon::Polygon() : edge_num(3) { color = 0 ; //默认颜色 for(int i = 0 ; i < edge_num; i++) point[i].x = point[i].y = 0; }
成员初始化参数表 Polygon::Polygon(int edgeNum) : edge_num(edgeNum) { color = 0 ; //默认颜色 for(int i = 0 ; i < edge_num; i++) point[i].x = point[i].y = 0; } 初始化 赋值
成员初始化参数表 Polygon::Polygon(char color , int edgeNum) : edge_num(edgeNum), line_color(color) { for(int i = 0 ; i < edge_num; i++) point[i].x = point[i].y = 0; } color可以在 函数体中赋值
成员初始化参数表 • 可以初始化: • 常量成员 • 变量成员(还可以在构造函数体中初始化) • 基类成员 • 对象成员 • 不可以初始化: • 静态成员
下列成员必须在成员初始化参数表中初始化: • 常量成员 • 引用成员 • 对象成员 • 基类成员 不能赋值 需要调用构造函数
对象成员的初始化 class Date { int year, month, day; public: Date(int y, int m, int d); }; class People { Date birthday; char name[20]; public: People(char *nm, int y, int m, int d); };
Date::Date(int y, int m, int d) { year = y; month = m; day = d; } People::People(char *nm, int y, int m, int d) : birthday(y,m,d) { strcpy(name, nm); }
默认构造函数 • 每个类必须有一个构造函数 • 如果没有定义构造函数,则C++提供默认构造函数(do nothing) • 如果定义了构造函数,则C++不再提供默认构造函数
默认构造函数 • 以下情况必须为类定义默认构造函数: File myfile; //无初始化值的对象 File files[20]; //对象数组 File *pFile = new File; //动态建立无初始化值的对象
析构函数 • 类的特殊的成员函数 • 构造函数 • 在类的对象创建时由系统自动调用的函数 • 析构函数 • 在类的对象生命期结束时由系统自动调用的函数
class File { //...... public: File(char * nm); //构造函数 ~File(); //析构函数 //...... }; File::~File() { delete [ ] contents; //释放文件空间 }
析构函数的特点 • 函数名为符号'~'加上类名 • 无返回值 • 无参数 • 由系统自动调用 • 必须是公有(public)成员 • 不可以重载
析构函数的意义 • 直接意义 • 在对象退出生命期前由系统调用的函数 • 间接意义 • 对象能正确、合理地退出生命期 • 如:释放占用资源,通知有关对象
调用构造函数 File f1("myfile"0) , * pFile= NULL ; void main() { pFile = new File("yourfile"); func(); } void func() { //...... delete pFile; } 调用析构函数
构造函数和析构函数 • 相同点 • 由系统自动调用 • 没有返回值 • 公有函数 • 不同点 • 作用不同,调用时间不同 • 构造函数可以重载,可以有参数
拷贝构造函数 void printFileInfor(File f); File getFile( FileList fl, int index); File a("myfile.cpp"); File b(a); printFileInfor(a); b = getFile(fl, 2); 调用拷贝 构造函数
拷贝构造函数 class File { ...... public: File(File & src); ...... }; File::File( File & src) { //文件内容的复制 }
拷贝构造函数 • 系统自动提供拷贝构造函数 • 系统提供的函数有时不正确 • 系统提供的函数只进行简单的复制操作 class File { char name[20]; char * contents; ...... }; 源文件 对象 contents 的内容 拷贝文件 对象