第三章 数据抽象
回顾 引用 默认参数 内联函数 函数重载
目标 类 成员变量 成员函数 this 指针 对象数组
类 定义数据的类型以及操作这些数据的函数 类的实例称为对象 类中的变量和函数称为成员
私有和公有 2-1 类成员可以在类的公有或者私有部分声明 数据成员通常在私有部分中声明 在公有部分中声明的成员可以被该类外部的函数访问 公有部分构成类的接口 private public
私有和公有 2-2 无法从类的外部访问私有数据 其他类的私有数据对于当前类也是隐藏的 类 私有 不可从类的外部访问 数据或函数 公有 可以从类的外部访问
const成员变量 常量的值在程序的执行期间不会改变 常量必须初始化 const int num=100; num = 200; //错误
成员函数 2-1 类的函数称为成员函数 成员函数通常放在类的公有部分 必须定义返回值及参数列表 例如 void setdate(int, int, int);
成员函数 2-2 成员函数可以有局部变量、参数等 成员函数不应与数据成员同名
调用成员函数 2-1 通过调用成员函数与对象通信 调用成员函数是操作特定的对象,而不是类 使圆点操作符与特定对象关联 object1.member_function1(200); object1.member_function2(); 调用成员函数是操作特定的对象,而不是类 使圆点操作符与特定对象关联
调用成员函数 2-2 访问类的成员函数的一般语法: class_object.function_member(); 成员操作符
构造函数 4-1 自动初始化对象的特殊的成员函数 与所属的类同名 可以在类中声明并定义构造函数,或在类中声明而在外部定义
构造函数 4-2 构造函数没有返回类型 默认构造函数是不带任何参数的构造函数 class username { public: }; username::username() { }
构造函数 4-3 class date{ int month, day, year; public: date() //默认构造函数 {day=1; month=1; year=1999;} date(int x) //仅指定日 {day=x; month=1; year=1999;} date(int x, int y, int z) //指定年月日 {day=x; month=y; year=z;} };
构造函数 4-4 编译器根据参数调用不同的构造函数 date now; date today(4); date all(23,3,1998);
析构函数 在对象销毁时自动调用的成员函数 编译器会生成对析构函数的调用 与类同名,但是在函数名前有个波浪号 (~) 析构函数没有返回类型,也不带参数 class username { public: ~username(); //析构函数 };
使用类 2-1 class exampleclass { private: int data; public: member_function1(parameter) assign value to data } member_function2() display data };
使用类 2-2 void main (){ //定义类exampleclass的对象 exampleclass object1,object2; //调用成员函数,将值200赋给data object1.member_function1(200); //调用显示数据的成员函数 object1.member_function2(); object2.member_function1(350); object2.member_function2(); }
作用域 2-1 使用作用域解析操作符(::)在类外定义成员函数 参数的类型必须与声明的类型完全匹配 return_type class_name::member_functions (arg1, arg2,..,argn) {} 参数的类型必须与声明的类型完全匹配
作用域 2-2 作用域操作符左侧是类名 将函数标识为特定类的成员 在全局与局部变量同名的情况下引用全局变量 ::global_variable 如果两个变量有不同的用途,它们的名称应该反映出这个区别
作用域表 位置 动作 { 定义时,调用构造函数 } 超出作用域,调用析构函数
静态成员 2-1 同一个类的所有对象共享数据项 只会为整个类创建一个静态数据项 只在类的内部可见 生命周期贯穿整个程序 static data_type variable;
静态成员 2-2 应该在 main( ) 程序开始之前创建并初始化 class race_cars{ private: static int Count; int car_number; char name[30]; public: race_cars(){count++;} //构造函数,用于增加count ~race_cars(){count--;} //析构函数,用于减小count }; int race_cars::count;
关于静态数据成员的更多内容 如果将一个静态成员声明为类的私有成员,则非成员函数不能访问它 是类的全局数据 不是对象的一部分,没有 this 指针
静态成员函数 不是对象的一部分,没有 this 指针 只能操纵类的静态数据成员
静态成员函数示例 class alpha { private: static int count; //静态数据 public: } static void display_count() //静态成员函数 cout << count; cout << endl; }; int alpha::count = 0; int main() { //在创建任何对象之前 alpha::display_count(); alpha obj1, obj2, obj3; //在创建了三个对象之后 return 0; }
this指针 编译器把调用成员函数的对象的地址赋给 this指针 可以像其他指向对象的指针一样使用this this -> age = 5; this -> getdata();
this的用法 class person{ private: int age; public: void display(); }; void Person::display(){ this -> age = 25; // 与age = 25一样 cout << this -> age; // 与cout << age一样 cout << endl; int main(){ Person Jack; Jack.display(); return 0; }
对象 每个对象对类中的数据成员都有其自己的副本 给定类的所有对象都使用相同的成员函数 在定义每个对象时数据就会存入内存,所以每个对象都有一个数据集
对象声明 对象 1 数据 1 数据 2 对象 2 对象 3 成员函数1() 成员函数2()
new 2-1 用于为类的对象创建内存空间 如果成功,返回指向所分配内存空间的指针 例如 data_type pointer_variable = new data_type; 例如 int *p; //指向int类型的指针 float *f; //指向float 类型的指针 p = new int; //为int类型分配内存 f = new float; //为float类型分配内存
new 2-2 内存空间不足或者检测到错误,返回空 new类似于C语言中所使用的malloc()函数 对于对象也是同样的语法 Student *stu_ptr; //指向Student类型对象的指针 stu_ptr = new Student; //指向新的Student对象
delete 2-1 delete显式销毁由new创建的对象 使用完内存后,使用delete将其释放 不要使用指向已经释放的内存的指针 int *ptr; ptr = new int; *ptr = 12; cout << *ptr; delete ptr; 使用完内存后,使用delete将其释放 不要使用指向已经释放的内存的指针
delete 2-2 分配由变长数组组成的内存块 使用new分配对象数组,必须在delete语句中使用[ ] int *ptr; ptr = new int[100]; delete [] ptr; 使用new分配对象数组,必须在delete语句中使用[ ] 使用delete删除由malloc分配的内存是错误的 使用free释放由new分配的内存也是错误的
对象数组 对象数组声明 对象数组使用 对象数组初始化 class_name object_array[length]; object_array[index].func(); 对象数组初始化 class_name object_array[length] = { class_name(arg1,arg2,…argn); …… }
对象指针 指针也可以指向对象 使用箭头操作符 (->) 访问成员 date *today_ptr;//指向date类型的对象的指针 today_ptr = new date;//指向新的date对象 使用箭头操作符 (->) 访问成员 today_ptr -> getdate();
总结 类 成员变量 成员函数 this 指针 对象数组