华东师范大学数学科学学院 目录页 School of Mathematical Sciences,ECNU Contents 1 类的组合 2 结构体与联合体 对象生存期 4 友元关系 http://math.ecnu.edu.cn/~jypan
http://math.ecnu.edu.cn/~jypan 目录页 Contents 华东师范大学 数学科学学院 School of Mathematical Sciences, ECNU http://math.ecnu.edu.cn/~jypan 1 2 类的组合 结构体与联合体 3 对象生存期 4 友元关系
类的组合一组合类 ■ 什么是组合类 ■组合类的初始化 ■常量和引用的初始化 前向引用声明 http://math.ecnu.edu.cn/~jypan 3
http://math.ecnu.edu.cn/~jypan 3 类的组合 — 组合类 什么是组合类 组合类的初始化 常量和引用的初始化 前向引用声明 1
类的组合 类的组合/聚合: 将已有的类的对象作为新的类的成员。 Example class Point /声明Point类 { public: 。。。。。。 private: double×,y }; class Line /声明Line类 public: 。。·。·0 private: Point p1,p2; } http://math.ecnu.edu.cn/~jypan
http://math.ecnu.edu.cn/~jypan 4 类的组合 类的组合/聚合: 将已有的类的对象作为新的类的成员。 class Point // 声明Point类 { public: ... ... private: double x, y; }; class Line // 声明Line类 { public: ... ... private: Point p1, p2; }; Example
组合类的初始化 在创建类的对象时,如果这个类包含其它类的对象(称为内嵌 对象成员),则各个内嵌对象将首先被自动创建。 组合类初始化: 内嵌对象成员初始化+普通数据成员初始化。 http://math.ecnu.edu.cn/~jypan 5
http://math.ecnu.edu.cn/~jypan 5 组合类的初始化 在创建类的对象时,如果这个类包含其它类的对象(称为内嵌 对象成员),则各个内嵌对象将首先被自动创建。 组合类初始化: 内嵌对象成员初始化 + 普通数据成员初始化
组合类的初始化 类名:类名(总的参数列表)内嵌对象1(参数),内嵌对象2(参数),· {类的数据成员的初始化;} 初始化列表:对内嵌对象进行初始化。 ·这里的“参数”前面不用加数据类型: ·初始化列表最前面有个冒号。 ·除了自身的构造函数外,内嵌对象的构造函数也被调用 ●构造函数调用顺序: 一按内嵌对象在组合类定义中出现的顺序依次调用内嵌数对象的构造函数 一最后调用本类的构造函数 ·析构函数的调用顺序与构造函数相反 http://math.ecnu.edu.cn/~jypan 6
http://math.ecnu.edu.cn/~jypan 6 组合类的初始化 类名::类名(总的参数列表) : 内嵌对象1(参数), 内嵌对象2(参数), ... {类的数据成员的初始化; } 初始化列表:对内嵌对象进行初始化。 ► 这里的“参数”前面不用加数据类型; ► 初始化列表最前面有个冒号。 除了自身的构造函数外,内嵌对象的构造函数也被调用 构造函数调用顺序: — 按内嵌对象在组合类定义中出现的顺序依次调用内嵌对象的构造函数 — 最后调用本类的构造函数 析构函数的调用顺序与构造函数相反
内嵌对象初始化:初始化列表 class Point //声明Point类 ex10_class_Line_01.cpp public: Point(double newx,double newy) /1构造函数 private: double x,y; } class Line /声明Line类 public: Line(double xA,double yA,double xB,double yB) :p1(xA,yA),p2(xB,yB){}/I组合类构造函数 private: Point p1,p2; 总的参数列表中的参数需要带数据类型(形参),初始化列表则不需要。 http://math.ecnu.edu.cn/~jypan
http://math.ecnu.edu.cn/~jypan 7 内嵌对象初始化:初始化列表 class Point // 声明Point类 { public: Point(double newx, double newy) // 构造函数 ... ... private: double x, y; }; class Line // 声明Line类 { public: Line(double xA, double yA, double xB, double yB) :p1(xA, yA),p2(xB,yB) { } // 组合类构造函数 ... ... private: Point p1, p2; }; ex10_class_Line_01.cpp † 总的参数列表中的参数需要带数据类型(形参),初始化列表则不需要
内嵌对象初始化:复制构造函数 口内嵌对象的初始化也可以在构造函数体内通过调用复制构造函数实现 但此时要求内嵌对象所属的类存在不需要提供数据的构造函数 (比如形参都带缺省值,或者存在不带形参的构造函数) class Point public: Point(double newx=0,double newy=0){x newx;y newy;} 川形参都带缺省值 ····· }; class Line public: Line(double xA,double yA,double xB,double yB) {p1=Point(A,yA);p2=Point(xB,yB);}∥函数体内初始化 ex10 class Line_02.cpp http://math.ecnu.edu.cn/-jypan
http://math.ecnu.edu.cn/~jypan 8 内嵌对象初始化:复制构造函数 class Point { public: Point(double newx=0, double newy=0) { x = newx; y = newy;} // 形参都带缺省值 ... ... }; class Line { public: Line(double xA, double yA, double xB, double yB) { p1=Point(xA, yA); p2=Point(xB,yB); } // 函数体内初始化 ... ... }; ex10_class_Line_02.cpp 内嵌对象的初始化也可以在构造函数体内通过调用复制构造函数实现 但此时要求内嵌对象所属的类存在不需要提供数据的构造函数 (比如形参都带缺省值,或者存在不带形参的构造函数)
内嵌对象初始化:复制构造函数 class Point public: Point(){x=;y=;}/∥存在不带形参的构造函数 Point(double newx,double newy){x newx;y newy;} } class Line public: Line(Point&A,Poin&B){pl=A;p2=B;}∥函数体内初始化 } ex10 class_Line_03.cpp http://math.ecnu.edu.cn/~jypan 9
http://math.ecnu.edu.cn/~jypan 9 内嵌对象初始化:复制构造函数 class Point { public: Point() {x = 0; y = 0;} // 存在不带形参的构造函数 Point(double newx, double newy) { x = newx; y = newy;} ... ... }; class Line { public: Line(Point & A, Poin & B) { p1=A; p2=B; } // 函数体内初始化 ... ... }; ex10_class_Line_03.cpp
常量和引用的初始化 ex10_class_const_ref.cpp class Myclass { public: lyclass(intx,inty,intz);/构造函数 。·。。。。 private: const int a; int b; int c; Myclass:Myclass(int x,int y,int z):a(x),b(y) {c=z;} 不能在类的声明中初始化任何数据成员! ↑数据成员中常量和引用的初始化:用初始化列表 http://math.ecnu.edu.cn/~jypan 10
http://math.ecnu.edu.cn/~jypan 10 常量和引用的初始化 class Myclass { public: Myclass(int x, int y, int z); // 构造函数 ... ... private: const int a; int & b; int c; }; Myclass::Myclass(int x, int y, int z) : a(x),b(y) { c=z; } ex10_class_const_ref.cpp † 不能在类的声明中初始化任何数据成员! † 数据成员中常量和引用的初始化:用初始化列表
前向引用声明 ·类必须先定义后使用 ●若两个类互相引用,则需要使用前向引用声明 Example class ClassB; /前向引用声明 class classA /声明A类 { public: void f(ClassB b); } class ClassB //声明B类 public: void g(ClassA a); 使用前向引用声明时,只能使用被声明的符号,而不能涉及类的任何细节。 http://math.ecnu.edu.cn/~jypan 11
http://math.ecnu.edu.cn/~jypan 11 前向引用声明 类必须先定义后使用 若两个类互相引用,则需要使用前向引用声明 class ClassB; // 前向引用声明 class ClassA // 声明 A 类 { public: void f(ClassB b); }; class ClassB // 声明 B 类 { public: void g(ClassA a); }; † 使用前向引用声明时,只能使用被声明的符号,而不能涉及类的任何细节。 Example