800 likes | 971 Views
第五章:类与对象. 罗月童 合肥工业大学, VCC 研究室. 类. 没有体现变量的内在联系?. 导 论. 导 论. 属 性. 循环计数器. 5.2 类的定义. 5.2.1 类申明 5.2.2 类成员的访问控制 5.2.3 类界面与类实现 5.2.4 标识符的类作用域. 成员变量. 成员函数. 5.2.1 类的申明. 类的成员变量. 和普通变量声明方法一样; 不允许使用表达式进行初始化 ; 不允许使用存储类别关键字 ( static 除外) 允许任何数据类型 不允许当前正在声明的类; 但允许当前正在声明的类的指针类型;.
E N D
第五章:类与对象 罗月童 合肥工业大学,VCC研究室
类 没有体现变量的内在联系? 导 论
5.2 类的定义 • 5.2.1 类申明 • 5.2.2 类成员的访问控制 • 5.2.3 类界面与类实现 • 5.2.4 标识符的类作用域
成员变量 成员函数 5.2.1 类的申明
类的成员变量 • 和普通变量声明方法一样; • 不允许使用表达式进行初始化; • 不允许使用存储类别关键字(static除外) • 允许任何数据类型 • 不允许当前正在声明的类; • 但允许当前正在声明的类的指针类型;
添加新的成员函数 输入13?
CIRCULAR_NUMBER Time; Time.min_val = 1; Time.max_val = 12; Time.set_value(13)
5.2.2 类成员的访问控制 private public
访问控制 • 访问控制:public, protected, private • 缺省访问控制方式为:private • private、public的出现顺序是任意的 • 如何配对? • 何时设为私有?何时设为公有?
访问控制封装性 • 一般将数据成员申明为私有的,而将成员函数设为公有的; • 内部可能发生很大变化,外部开不见; • 辅助函数也可以设为私有的; • 迫使他人按你的意图使用代码…
属性 方法 接口 封装性(Encapsulation) • 封装性(Encapsulation):是一种信息隐藏技术; • 封装性定义为: • 一个清楚的边界 • 一个接口 • 受保护的内部实现
也可用struct,区别在于:如使用class关键字,类成员默认是私有的,如使用struct关键字,类成员默认是公有的。也可用struct,区别在于:如使用class关键字,类成员默认是私有的,如使用struct关键字,类成员默认是公有的。 class 类名标识符 { }; private: 私有成员说明 public: 公有成员说明 protected: 保护成员说明 访 问 限 制 数据成员和成员函数
5.2.3 类界面和类实现 • 在同一个文件中 • 声明和实现混合在一起 • 声明和实现混合分开 • 在不同文件中
5.3 对象的创建 • 5.3.1 对象声明 • 5.3.2 使用对象成员 • 5.3.3 对象的生存期
对象、实例 如何分配内存? 5.3.1 对象声明
this 指针 • this指针是隐含在成员函数内的一种常量指针; • 每当向一个对象发送消息从而执行成员函数时,系统自动向该成员函数传递一个隐含的参数,该参数是该对象的指针(地址),赋给this指针;
5.3.3 对象的生存期 • 局部对象: • 当对象被定义时,该对象被创建,当程序退出定义该对象的函数体或程序块时,释放该对象; • 静态对象: • 当程序第一次执行所定义的静态对象时,该对象被创建,程序结束时,释放该对象; • 全局对象: • 程序开始时被创建,程序结束时被释放;
5.4 对象的初始化 • 5.4.1 构造函数 • 5.4.2 析构函数 • 5.4.3 new、delete运算符 • 5.4.3 对象成员的初始化
5.4.1 构造函数 • 描述: • 一种特殊的成员函数 • 函数的名子与类的名子相同; • 不能指定返回值,void也不行; • 调用: • 创建对象是被调用;
请写出输出… 有、无构造函数的区别?
回忆:函数重载…… • C ++允许在同一作用域中用同一函数名定义多个函数 • 这些函数的参数个数和参数类型不同
构造函数没有返回值? • 构造函数在申明对象时调用,无法处理返回值; • 构造函数的功能不能太复杂 • 万一出现问题,如何处理? • 强调: • 创建对象是被调用
缺省构造函数 • 程序员没有定义构造函数时,系统自动定义缺省构造函数: • 没有参数…… • 函数体为空…...
构造函数小结 • 与类同名的成员函数 • 无返回类型 • 可重载 • 如无定义,系统会自动生成缺省的构造函数 • 构造函数在创建对象时被系统自动调用
写出下列程序段的输出 • class A{ • private: • int val; • public: • A (int value) { • val = value; • cout << "val = “ << val<<endl; • } • A() { • cout << “default constructor\n” • } • };
写出下列程序段的输出 • int main () • { • cout << "Begin of main"<<endl; • A obj1(1); • A obj2; • cout << "End of main"<<endl; • return 0; • }
写出下列程序段的输出 • A obj3(3); • int main() • { • cout << "Begin of main"<<endl; • A obj1(1); • A obj2; • cout << "End of main"<<endl; • return 0; • }
写出下列程序段的输出 • void f(int val) • { • cout << “begin of f\n”; • A obj (val); • cout << “end of f\n”; • }
写出下列程序段的输出 • int main() • { • cout << "Begin of main"<<endl; • f(3); • cout << “----------------"<<endl; • f(3); • cout << "End of main"<<endl; • return 0; • }
写出下列程序段的输出 • void f(int val) • { • cout << “begin of f\n”; • static A obj (val); • cout << “end of f\n”; • }
5.4.2 析构函数 • 释放对象时被调用,用于执行一些清理工作; • ~函数名 • 没有返回值 • 没有参数; 可以有多个析构函数吗?
写出下列程序段的输出 • class A{ • private: • int val; • public: • A (int value) { • val = value; • } • A() {} • ~A(){ cout << “destructor: val = “<< val << endl;} • };
写出下列程序段的输出 • int main () • { • cout << "Begin of main"<<endl; • A obj1(1); • A obj2; • cout << "End of main"<<endl; • return 0; • }
写出下列程序段的输出 • A obj3(3); • int main() • { • cout << "Begin of main"<<endl; • A obj1(1); • A obj2; • cout << "End of main"<<endl; • return 0; • }
写出下列程序段的输出 • void f(int val) • { • cout << “begin of f\n”; • A obj (val); • cout << “end of f\n”; • }
写出下列程序段的输出 • int main() • { • cout << "Begin of main"<<endl; • f(3); • cout << “----------------"<<endl; • cout << "End of main"<<endl; • return 0; • }
写出下列程序段的输出 • void f(int val) • { • cout << “begin of f\n”; • static A obj (val); • cout << “end of f\n”; • }
5.4.4 new、delete运算符(P210) • 指针= new类型名(初始化列表); • 指针= new类型名[表达式]; • delete指针; • delete []指针; 完全控制对象的创建和销毁!
class A{ public: A(){cout << "A Constructor\n";} ~A(){cout << "A Destructor\n";} }; class B{ public: B(){cout << "B Constructor\n";} ~B(){cout << "B Destructor\n";} }; void main() { cout << "Begin....\n"; A a; B b; A *pA = new A[3]; B *pB = new B; delete []pA; cout << "End....\n"; } 5.4.4 new、delete运算符(P210)
class A{ public: A() {cout << "constructor\n";}; ~A(){cout << "destructor\n";}; }; class Array{ public: Array(int n) { pData = new A[n]; }; ~Array() { delete []pData;}; private: A *pData; }; void main() { int n; cin>> n; Array a(n); } 动态数组 析构函数的重要性