程序设计与算法语言 拷贝构造 C/C++ Programming and Algorithms Copy Constructor Dongke Sun ( 孙东科 ) 东南大学机械工程学院 School of Mechanical Engineering South

Size: px
Start display at page:

Download "程序设计与算法语言 拷贝构造 C/C++ Programming and Algorithms Copy Constructor Dongke Sun ( 孙东科 ) 东南大学机械工程学院 School of Mechanical Engineering South"

Transcription

1 程序设计与算法语言 拷贝构造 C/C++ Programming and Algorithms Copy Constructor Dongke Sun ( 孙东科 ) dksun@seu.edu.cn 东南大学机械工程学院 School of Mechanical Engineering Southeast University Spring semester, 2019

2 视 C++ 为一个语言联邦 Scott Meyers Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

3 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

4 提纲 1 拷贝构造函数 2 构造函数与类型转换 3 构造函数与对象成员 4 对象成员的初始化 5 总结与思考 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

5 提纲 拷贝构造函数 1 拷贝构造函数 2 构造函数与类型转换 3 构造函数与对象成员 4 对象成员的初始化 5 总结与思考 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

6 拷贝构造函数为什么需要拷贝构造函数 尝试分析下面程序出错的原因 1 class Student 2 { 3 int Age; 4 public: 5 char *Name; // 注意 : 指针 6 Student(char *name, int age) 7 { 8 if(name) // 动态申请空间 9 { 10 Name = new char [ strlen(name)+1]; 11 strcpy(name, name); 12 } 13 else Name= NULL; 14 } 15 ~Student( ) // 释放空间 16 { 17 if(name) delete [] Name; 18 } 19 }; 20 Student change(char *name, int age ) 21 { 22 Student c(name,age); 23 return c; 24 } 25 int display(student b) 26 { 27 cout << b.name << endl; 28 return 1; 29 } 25 int main() 26 { 27 Student a("michael", 18); 28 Student b=a; // 出错! 29 int flag=display(a); // 出错! 30 b=change("annie",20);// 出错! 31 return 0; 32 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

7 拷贝构造函数为什么需要拷贝构造函数 前提条件 尝试分析下面程序出错的原因类中有数据成员使用 new 动态地申请了内存空间 1 class Student 2 { 3 int Age; 4 public: 5 char *Name; // 注意 : 指针 6 Student(char *name, int age) 7 { 8 if(name) // 动态申请空间 9 { 10 Name = new char [ strlen(name)+1]; 11 strcpy(name, name); 12 } 13 else Name= NULL; 14 } 15 ~Student( ) // 释放空间 16 { 17 if(name) delete [] Name; 18 } 19 }; 20 Student change(char *name, int age ) 21 { 22 Student c(name,age); 23 return c; 24 } 25 int display(student b) 26 { 27 cout << b.name << endl; 28 return 1; 29 } 25 int main() 26 { 27 Student a("michael", 18); 28 Student b=a; // 出错! 29 int flag=display(a); // 出错! 30 b=change("annie",20);// 出错! 31 return 0; 32 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

8 拷贝构造函数为什么需要拷贝构造函数 前提条件 尝试分析下面程序出错的原因类中有数据成员使用 new 动态地申请了内存空间 1 class Student 20 Student change(char *name, int age 2 三处 { 出错 对应于 ) 3 int Age; 21 { 4 public: 类的一个对象初始化另外一个对象 : 赋值初始化 22 Student c(name,age); 5 类的对象作为函数的参数 char *Name; // 注意 : 指针, 以值传递的方式传入 23 return c; 6 Student(char *name, int age) 24 } 7 类的对象作为函数返回值 {, 以值传递的方式返回 25 int display(student b) 8 if(name) // 动态申请空间 26 { 9 { 27 cout << b.name << endl; 10 Name = new char [ 28 return 1; strlen(name)+1]; 29 } 11 strcpy(name, name); 12 } 25 int main() 13 else Name= NULL; 26 { 14 } 27 Student a("michael", 18); 15 ~Student( ) // 释放空间 28 Student b=a; // 出错! 16 { 29 int flag=display(a); // 出错! 17 if(name) delete [] Name; 30 b=change("annie",20);// 出错! 18 } 31 return 0; 19 }; 32 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

9 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 拷贝 ( 复制 ) 构造函数 是一种特殊的构造函数 它由编译器调用来完成一些基于同一类的其他对象的构建及初始化 其一般格式为 1 ClassName :: ClassName( [const] ClassName & Obj ) // 注意 : 引用 2 { 函数体 <> } 拷贝构造函数唯一的形参必须是该类对象的引用, 一般会加上 const 限制 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

10 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 拷贝 ( 复制 ) 构造函数 是一种特殊的构造函数 它由编译器调用来完成一些基于同一类的其他对象的构建及初始化 其一般格式为 1 ClassName :: ClassName( [const] ClassName & Obj ) // 注意 : 引用 2 { 函数体 <> } 拷贝构造函数唯一的形参必须是该类对象的引用, 一般会加上 const 限制 如果不定义拷贝构造函数, 则由编译器自动产生一个默认 ( 缺省 ) 的拷贝构造函数 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

11 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 拷贝 ( 复制 ) 构造函数 是一种特殊的构造函数 它由编译器调用来完成一些基于同一类的其他对象的构建及初始化 其一般格式为 1 ClassName :: ClassName( [const] ClassName & Obj ) // 注意 : 引用 2 { 函数体 <> } 拷贝构造函数唯一的形参必须是该类对象的引用, 一般会加上 const 限制 如果不定义拷贝构造函数, 则由编译器自动产生一个默认 ( 缺省 ) 的拷贝构造函数 当类中有动态申请的成员空间时, 务必定义一个拷贝构造函数, 用以避免内存异常 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

12 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 拷贝 ( 复制 ) 构造函数 是一种特殊的构造函数 它由编译器调用来完成一些基于同一类的其他对象的构建及初始化 其一般格式为 1 ClassName :: ClassName( [const] ClassName & Obj ) // 注意 : 引用 2 { 函数体 <> } 拷贝构造函数唯一的形参必须是该类对象的引用, 一般会加上 const 限制 如果不定义拷贝构造函数, 则由编译器自动产生一个默认 ( 缺省 ) 的拷贝构造函数 当类中有动态申请的成员空间时, 务必定义一个拷贝构造函数, 用以避免内存异常 定义拷贝构造函数的时机 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

13 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 拷贝 ( 复制 ) 构造函数 是一种特殊的构造函数 它由编译器调用来完成一些基于同一类的其他对象的构建及初始化 其一般格式为 1 ClassName :: ClassName( [const] ClassName & Obj ) // 注意 : 引用 2 { 函数体 <> } 拷贝构造函数唯一的形参必须是该类对象的引用, 一般会加上 const 限制 如果不定义拷贝构造函数, 则由编译器自动产生一个默认 ( 缺省 ) 的拷贝构造函数 当类中有动态申请的成员空间时, 务必定义一个拷贝构造函数, 用以避免内存异常 定义拷贝构造函数的时机 当只需要拷贝同一个类不同对象的部分数据成员时, 以及 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

14 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 拷贝 ( 复制 ) 构造函数 是一种特殊的构造函数 它由编译器调用来完成一些基于同一类的其他对象的构建及初始化 其一般格式为 1 ClassName :: ClassName( [const] ClassName & Obj ) // 注意 : 引用 2 { 函数体 <> } 拷贝构造函数唯一的形参必须是该类对象的引用, 一般会加上 const 限制 如果不定义拷贝构造函数, 则由编译器自动产生一个默认 ( 缺省 ) 的拷贝构造函数 当类中有动态申请的成员空间时, 务必定义一个拷贝构造函数, 用以避免内存异常 定义拷贝构造函数的时机 当只需要拷贝同一个类不同对象的部分数据成员时, 以及 当类中某个数据成员是动态地申请内存并赋初值时 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

15 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 拷贝 ( 复制 ) 构造函数 是一种特殊的构造函数 它由编译器调用来完成一些基于同一类的其他对象的构建及初始化 其一般格式为 1 ClassName :: ClassName( [const] ClassName & Obj ) // 注意 : 引用 2 { 函数体 <> } 拷贝构造函数唯一的形参必须是该类对象的引用, 一般会加上 const 限制 如果不定义拷贝构造函数, 则由编译器自动产生一个默认 ( 缺省 ) 的拷贝构造函数 当类中有动态申请的成员空间时, 务必定义一个拷贝构造函数, 用以避免内存异常 定义拷贝构造函数的时机 当只需要拷贝同一个类不同对象的部分数据成员时, 以及 当类中某个数据成员是动态地申请内存并赋初值时 必须显式地定义一个完成拷贝功能的构造函数, 以实现数据成员的复制 ; 还应 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

16 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 拷贝 ( 复制 ) 构造函数 是一种特殊的构造函数 它由编译器调用来完成一些基于同一类的其他对象的构建及初始化 其一般格式为 1 ClassName :: ClassName( [const] ClassName & Obj ) // 注意 : 引用 2 { 函数体 <> } 拷贝构造函数唯一的形参必须是该类对象的引用, 一般会加上 const 限制 如果不定义拷贝构造函数, 则由编译器自动产生一个默认 ( 缺省 ) 的拷贝构造函数 当类中有动态申请的成员空间时, 务必定义一个拷贝构造函数, 用以避免内存异常 定义拷贝构造函数的时机 当只需要拷贝同一个类不同对象的部分数据成员时, 以及 当类中某个数据成员是动态地申请内存并赋初值时 必须显式地定义一个完成拷贝功能的构造函数, 以实现数据成员的复制 ; 还应 显式地定义相应的析构函数, 用以撤消动态分配的空间 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

17 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 拷贝构造函数唯一的形参必须是该类对象的引用, 一般会加上 const 限制 1 class A 2 { 3 private: 4 int value; 5 public: 6 A(int n) { value = n; } 7 A(A other) { value = other.value; } 8 void Print() { cout << value << endl; } 9 }; 10 int main(void) 11 { 12 A a = 10; 13 A b = a; 14 b.print(); 15 return 0; 16 } 分析上述代码编译运行结果, 下列说法正确的是 :( ) A. 编译错误 B. 编译成功, 运行时程序崩溃 C. 编译错误, 缺少默认构造函数 D. 编译运行正常, 输出 10 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

18 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 拷贝构造函数唯一的形参必须是该类对象的引用, 一般会加上 const 限制 1 class A 2 { 3 private: 4 int value; 5 public: 6 A(int n) { value = n; } 7 A(A other) { value = other.value; } 8 void Print() { cout << value << endl; } 9 }; 10 int main(void) 11 { 12 A a = 10; 13 A b = a; 14 b.print(); 15 return 0; 16 } 分析上述代码编译运行结果, 下列说法正确的是 :( A ) A. 编译错误 B. 编译成功, 运行时程序崩溃 C. 编译错误, 缺少默认构造函数 D. 编译运行正常, 输出 10 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

19 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 分析拷贝构造函数唯一的形参必须是该类对象的引用, 一般会加上 const 限制 拷贝构造函数 A(A other) 传入的参数是类 A 的一个实例 由于是传值, 形 1 class A 参传递给实参时会调用拷贝构造函数 2 { 3 如果允许传值 private:, 就会在拷贝构造函数内调用拷贝构造函数, 从而形成永无 4 休止的循环调用并最终导致栈溢出 int value; 5 public: 6 A(int n) { value = n; } 注意 7 A(A other) { value = other.value; } 8 不允许复制构造函数传值参数 void Print() { cout << value, 只能将构造函数修改为引用参数 例如 << endl; }, 9 }; 可将传值参数改为常量引用 10 int main(void) :const A & other 11 传指针也是不允许的 {, 只能改为该类对象的引用或常量引用 12 A a = 10; 13 A b = a; 14 b.print(); 15 return 0; 16 } 分析上述代码编译运行结果, 下列说法正确的是 :( A ) A. 编译错误 B. 编译成功, 运行时程序崩溃 C. 编译错误, 缺少默认构造函数 D. 编译运行正常, 输出 10 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

20 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 如果不定义拷贝构造函数, 则由编译器自动产生一个默认 ( 缺省 ) 的拷贝构造函数 1 class Point 2 { 3 int x, y; 4 public: 5 Point(int a=0, int b=0) // 缺省构造函数 6 { x=a; y=b; } 7 8 ~Point( ) // 析构函数 9 {... } 10 void Show( ) 11 {... } 12 int Getx( ) 13 { return x; } 14 int Gety( ) 15 { return y; } 16 }; int main( ) 24 { 25 Point p1(6, 8), p2(4, 7); 26 Point p3(p1); // 调用拷贝构造 27 Point p4=p2; // 调用拷贝构造 28 p1.show( ); 29 p3.show( ); 30 p2.show( ); 31 p4.show( ); 32 return 0; 33 } 尽管没有定义拷贝构造函数, 但在调用时编译器会生成默认的拷贝构造函数 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

21 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 如果不定义拷贝构造函数, 则编译器会自动生成一个默认 ( 缺省 ) 的拷贝构造函数 如果用户定义了拷贝构造函数呢? 1 class Point 2 { 3 int x, y; 4 public: 5 Point(int a=0, int b=0) // 默认构造函数 6 { x=a; y=b; } 7 Point(Point &p); // 拷贝构造 8 ~Point( ) // 析构函数 9 {... } 10 void Show( ) 11 {... } 12 int Getx( ) 13 { return x; } 14 int Gety( ) 15 { return y; } 16 }; 17 // 定义拷贝构造函数 18 Point::Point(Point &p) 19 { 20 x=p.x; y=p.y; } 23 int main( ) 24 { 25 Point p1(6, 8), p2(4, 7); 26 Point p3(p1); // 调用拷贝构造 27 Point p4=p2; // 调用拷贝构造 28 p1.show( ); 29 p3.show( ); 30 p2.show( ); 31 p4.show( ); 32 return 0; 33 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

22 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 如果不定义拷贝构造函数, 则编译器会自动生成一个默认 ( 缺省 ) 的拷贝构造函数 如果用户定义了拷贝构造函数呢? 1 class Point 2 { 3 int x, y; 4 public: 5 Point(int a=0, int b=0) // 默认构造函数 6 { x=a; y=b; } 7 Point(Point &p); // 拷贝构造 8 ~Point( ) // 析构函数 9 {... } 10 void Show( ) 11 {... } 12 int Getx( ) 13 { return x; } 14 int Gety( ) 15 { return y; } 16 }; 17 // 定义拷贝构造函数 18 Point::Point(Point &p) 19 { 20 x=p.x; y=p.y; } 23 int main( ) 24 { 25 Point p1(6, 8), p2(4, 7); 26 Point p3(p1); // 调用拷贝构造 27 Point p4=p2; // 调用拷贝构造 28 p1.show( ); 29 p3.show( ); 30 p2.show( ); 31 p4.show( ); 32 return 0; 33 } 此时, 用户定义了拷贝构造函数, 编译器就不再生成默认的拷贝构造函数 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

23 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 分析并写出用户定义和不定义拷贝构造函数两种情况下的程序输出结果 1 class Point 2 { 3 int x, y; 4 public: 5 Point(int a=0, int b=0) { x=a; y=b; } // 缺省构造函数 6 Point(Point &p) // 拷贝构造函数, 删除后呢? 7 { x=p.x; y=p.y; 8 cout<<x<<, <<y<<" Copy-initialization Constructor Called.\n"; } 9 ~Point( ) { cout<<x<<, <<y<<" Destructor Called.\n" ; } 10 void Show( ) { cout<<"point: "<<x<<, <<y<<endl; } 11 int Getx( ) { return x; } int Gety( ) { return y; } 12 }; 13 int main( ) 14 { 15 Point p1(6, 8), p2(4, 7); 16 Point p3(p1); // 调用拷贝构造函数 17 Point p4 = p2; // 调用拷贝构造函数 18 p1.show( ); p3.show( ); p2.show( ); p4.show( ); 19 return 0; 20 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

24 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 程序运行结果分析并写出用户定义和不定义拷贝构造函数两种情况下的程序输出结果 定义拷贝构造函数 6, 1 8class Copy-initialization Point Constructor Called. 2 4, 7{ Copy-initialization Constructor Called. 3 int x, y; Point: 6, 8 4 public: Point: 5 Point(int 6, 8 a=0, int b=0) { x=a; y=b; } // 缺省构造函数 Point: 6 Point(Point 4, 7 &p) // 拷贝构造函数, 删除后呢? 7 Point: { 4, x=p.x; 7 y=p.y; 8 cout<<x<<, <<y<<" Copy-initialization Constructor Called.\n"; } 4, 7 Destructor 9 ~Point( ) Called. { cout<<x<<, <<y<<" Destructor Called.\n" // 撤销 P4 ; } 6, 10 8 Destructor void Show( ) Called. { cout<<"point: "<<x<<, <<y<<endl; // 撤销 P3 } 4, 11 7 Destructor int Getx( ) Called. { return// x; 撤销 } P2 int Gety( ) { return y; } 12 6, 8}; Destructor Called. 13 int main( ) // 撤销 P1 请测试删除拷贝构造函数时以上代码的运行结果 14 { 15 Point p1(6, 8), p2(4, 7); 16 Point p3(p1); // 调用拷贝构造函数 17 Point p4 = p2; // 调用拷贝构造函数 18 p1.show( ); p3.show( ); p2.show( ); p4.show( ); 19 return 0; 20 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

25 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 程序运行结果分析并写出用户定义和不定义拷贝构造函数两种情况下的程序输出结果 定义拷贝构造函数 6, 1 8class Copy-initialization Point Constructor Called. 2 4, 7{ Copy-initialization Constructor Called. 3 int x, y; Point: 程序运行结果 6, 8 4 public: 不定义拷贝构造函数 Point: 5 Point(int 6, a=0, int b=0) { x=a; y=b; } // 缺省构造函数 Point: 6, 8 Point: 6 Point(Point 4, 7 &p) // 拷贝构造函数, 删除后呢? Point: 7 { 6, x=p.x; 8 Point: 4, y=p.y; Point: 8 4, cout<<x<<, <<y<<" Copy-initialization Constructor Called.\n"; 7 } 4, 7 Destructor 9 ~Point( ) Called. { cout<<x<<, <<y<<" Destructor Called.\n" // 撤销 P4 Point: 4, 7 ; } 6, 10 8 Destructor void Show( ) Called. { cout<<"point: "<<x<<, <<y<<endl; // 撤销 P3 } 4, 7 Destructor Called. // 撤销 P4 4, 11 Destructor int Getx( ) Called. { return// x; 撤销 } P2 int Gety( ) { return y; } 6, 12 8}; Destructor Called. // 撤销 P3 6, Destructor Called. // 撤销 P1 4, 13 7intDestructor main( ) Called. // 撤销 P2 请测试删除拷贝构造函数时以上代码的运行结果 14 6, 8{ Destructor Called. // 撤销 P1 15 Point p1(6, 8), p2(4, 7); 16 Point p3(p1); // 调用拷贝构造函数 17 Point p4 = p2; // 调用拷贝构造函数 18 p1.show( ); p3.show( ); p2.show( ); p4.show( ); 19 return 0; 20 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

26 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 当类中有动态申请空间的成员时, 务必定义一个拷贝构造函数以避免异常 1 class Student 2 { 3 int Age; 4 public: 5 char *Name; // 注意 : 指针 6 Student(char *name, int age) 7 { 8 if(name) // 动态申请空间 9 { 10 Name = new char [ strlen(name)+1]; 11 strcpy(name, name); 12 } 13 else Name= NULL; 14 } 15 ~Student( ) // 释放空间 16 { 17 if(name) delete [] Name; 18 } 19 }; 20 Student change(char *name, int age ) 21 { 22 Student c(name,age); 23 return c; 24 } 25 int display(student b) 26 { 27 cout << b.name << endl; 28 return 1; 29 } 25 int main() 26 { 27 Student a("michael", 18); 28 Student b=a; // 出错! 29 int flag=display(a); // 出错! 30 b=change("annie",20);// 出错! 31 return 0; 32 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

27 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 解决之道 当类中有动态申请空间的成员时, 务必定义一个拷贝构造函数以避免异常 在类中显示地 ( 手工 ) 定义一个拷贝构造函数, 用以避免产生内存异常 1 class Student 20 Student change(char *name, int age 2 { ) 3 int Age; 21 { 4 public: 22 Student c(name,age); 5 char *Name; // 注意 : 指针 23 return c; 6 Student(char *name, int age) 24 } 7 { 25 int display(student b) 8 if(name) // 动态申请空间 26 { 9 { 27 cout << b.name << endl; 10 Name = new char [ 28 return 1; strlen(name)+1]; 29 } 11 strcpy(name, name); 12 } 25 int main() 13 else Name= NULL; 26 { 14 } 27 Student a("michael", 18); 15 ~Student( ) // 释放空间 28 Student b=a; // 出错! 16 { 29 int flag=display(a); // 出错! 17 if(name) delete [] Name; 30 b=change("annie",20);// 出错! 18 } 31 return 0; 19 }; 32 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

28 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 编译器自动提供的拷贝构造函数如下 : 1 Student::Student(const Student &s) 2 { 3 Name = s.name; // 注意 : 地址值直接赋值 4 Age = s.age; 5 } 正确的做法是, 手工定义拷贝构造函数 例如 1 Student::Student(const Student &s) 2 { 3 Age = s.age; 4 if(s.name) 5 { 6 Name = new char[strlen(s.name)+1]; //C 7 strcpy(name, s.name); 8 } 9 else 10 Name=NULL; 11 } 请在 CodeBlocks 中测试 StudentCopy.cpp Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

29 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 阅读并分析出错原因 程序代码如下 1 class Student { 2 char *Name; // 姓名, 用指针实现 3 int Age; // 年龄 4 public: 5 Student(char *name, int age) { // 构造函数 6 Age=age; 7 if(name) // 在构造函数中, 需动态申请空间 8 { Name=new char[strlen(name)+1]; strcpy(name, name); } 9 else 10 { Name=NULL; } 11 } 12 // 因在构造函数中动态申请了内存空间, 则在析构函数中, 需释放内存空间 13 ~Student( ) { if(name) delete [ ] Name; } 14 void Show( ) { cout << Name <<, << Age << endl; } 15 }; 16 int main( ) { 17 Student a("george", 20); 18 Student b = a; // 19 return 0; 20 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

30 拷贝构造函数拷贝构造函数和缺省拷贝构造函数 阅读并分析出错原因 程序代码如下 1 class Student { 2 char *Name; // 姓名, 用指针实现 3 int Age; // 年龄 4 public: 5 Student(char *name, int age) { // 构造函数 6 Age=age; 7 if(name) // 在构造函数中, 需动态申请空间 8 { Name=new char[strlen(name)+1]; strcpy(name, name); } 9 else 10 { Name=NULL; } 11 } 12 // 因在构造函数中动态申请了内存空间, 则在析构函数中, 需释放内存空间 13 ~Student( ) { if(name) delete [ ] Name; } 14 void Show( ) { cout << Name <<, << Age << endl; } 15 }; 16 int main( ) { 17 Student a("george", 20); 18 Student b = a; // 错误 : 执行拷贝初始化, 但没有定义类的拷贝构造函数 19 return 0; 20 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

31 拷贝构造函数拷贝构造函数的调用时机 当利用同一个类的其他对象产生新对象时, 系统自动调用拷贝构造函数 那么, 产生新对象发生在什么时候? 1 明确表示由一个对象初始化另一个对象时 例如 1 Point p3(p1); // A 调用拷贝构造函数 2 Point p4 = p2; // B 调用拷贝构造函数 2 当用对象作为函数参数时, 用实参对象初始化形参对象时 ; 以及 3 当函数返回对象时, 用返回值对象初始化内存临时对象时 例如 1 Point move(point p, int xoffset, int yoffset) // Point p=p1 值传递 ; 2 { 3...; return t; // 返回时创建临时对象临时对象 _t (t 的副本 ) 4 } 请在 CodeBlocks 中运行 PointTest.cpp, 测试 用对象做函数参数, 以及 用对象做函数返回值 两种情况下拷贝构造函数的用法 注意观察拷贝构造函数的调用时机 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

32 拷贝构造函数拷贝构造函数的调用时机 理解拷贝构造函数的用法, 注意拷贝构造函数的调用时机 1 #include <iostream> 2 #include "./Point.h" 3 using namespace std; 4 5 // 注意 :move 是普通函数, 不是类的成员函数 6 Point move(point p, int xoffset, int yoffset) // A Point p=p1 参数传递 7 { 8 int x = p.getx( )+xoffset; 9 int y = p.gety( )+yoffset; 10 Point t(x, y); 11 return t; // B 12 } 13 int main( ) 14 { 15 Point p1(6, 8), p2; 16 p2 = move(p1, 2, 4); // A, B 对象为函数参数, 用实参对象初始化形参对象 return 0; 19 } 此程序运行结果是? Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

33 拷贝构造函数拷贝构造函数的调用时机 理解拷贝构造函数的用法, 注意拷贝构造函数的调用时机 1 #include <iostream> 2 #include "./Point.h" 3 using namespace std; 4 5 // 注意 :move 是普通函数, 不是类的成员函数 6 Point move(point p, int xoffset, int yoffset) // A Point p=p1 参数传递 7 { 8 int x = p.getx( )+xoffset; 9 int y = p.gety( )+yoffset; 10 Point t(x, y); 11 return t; // B 返回时创建临时对象 _t 调用拷贝构造; 先后撤销 t p 和 _t 12 } 13 int main( ) 14 { 15 Point p1(6, 8), p2; 16 p2 = move(p1, 2, 4); // A, B 对象为函数参数, 用实参对象初始化形参对象 return 0; 19 } 此程序运行结果是? Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

34 程序运行结果 VS2017 拷贝构造函数 拷贝构造函数的调用时机 6, 8 Copy-initialization Constructor Called. // A 8, 12 Copy-initialization Constructor Called. // B 创建临时对象 8, 理解拷贝构造函数的用法 12 Destructor Called., 注意拷贝构造函数的调用时机 // 撤消对象 t 6, 8 Destructor Called. // 撤消对象 p 1 #include <iostream> 8, 12 2 #include Destructor "./Point.h" Called. // 撤消临时对象 8, 3 12 using Destructor namespace std; Called. // 撤消对象 p2 6, 4 8 Destructor Called. // 撤消对象 p1 5 // 注意 :move 是普通函数, 不是类的成员函数 6 Point move(point p, int xoffset, int yoffset) // A Point p=p1 参数传递 7 { 8 int x = p.getx( )+xoffset; 9 int y = p.gety( )+yoffset; 10 Point t(x, y); 11 return t; // B 返回时创建临时对象 _t 调用拷贝构造; 先后撤销 t p 和 _t 12 } 13 int main( ) 14 { 15 Point p1(6, 8), p2; 16 p2 = move(p1, 2, 4); // A, B 对象为函数参数, 用实参对象初始化形参对象 return 0; 19 } 此程序运行结果是? Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

35 程序运行结果 VS2017 拷贝构造函数 拷贝构造函数的调用时机 6, 8 Copy-initialization Constructor Called. // A 8, 12 Copy-initialization Constructor Called. // B 创建临时对象 8, 理解拷贝构造函数的用法 12 Destructor Called., 注意拷贝构造函数的调用时机 // 撤消对象 t 6, 8 Destructor Called. // 撤消对象 p 1 #include <iostream> 8, 12 2 #include Destructor "./Point.h" Called. // 撤消临时对象 8, 3 12 using Destructor namespace std; Called. // 撤消对象 p2 6, 4 8 Destructor Called. // 撤消对象 p1 5 // 注意 :move 是普通函数, 不是类的成员函数 6 Point move(point p, int xoffset, int yoffset) // A Point p=p1 参数传递 7 { 8 int x = p.getx( )+xoffset; 9 int y = p.gety( )+yoffset; 10 Point t(x, y); 11 return t; // B 返回时创建临时对象 _t 调用拷贝构造; 先后撤销 t p 和 _t 12 } 13 int main( ) 14 { 15 Point p1(6, 8), p2; 16 p2 = move(p1, 2, 4); // A, B 对象为函数参数, 用实参对象初始化形参对象 return 0; 19 } 此程序运行结果是? 不同编译器对返回的处理方式不同, 输出结果因而不同 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

36 程序运行结果 VS2017 拷贝构造函数 拷贝构造函数的调用时机 6, 8 Copy-initialization Constructor Called. // A 8, 12 Copy-initialization Constructor Called. // B 创建临时对象 8, 理解拷贝构造函数的用法 12 Destructor Called., 注意拷贝构造函数的调用时机 // 撤消对象 t 6, 8 Destructor Called. // 撤消对象 p 1 #include <iostream> 8, 12 2 #include Destructor "./Point.h" Called. // 撤消临时对象 8, 3 12 using Destructor namespace std; Called. // 撤消对象 p2 6, 4 8 Destructor Called. // 撤消对象 p1 5 // 注意 :move 是普通函数, 不是类的成员函数 6 Point move(point p, int xoffset, int yoffset) // A Point p=p1 参数传递程序运行结果 GCC { 6, 8 8 Copy-initialization int x = p.getx( )+xoffset; Constructor Called. // A 9 8, 12 Destructor int y = p.gety( Called. )+yoffset; // 撤消对象 t 10 Point t(x, y); 6, 8 Destructor 11 return t; // Called. B 返回时创建临时对象 // 撤消对象 _t 调用拷贝构造 p ; 先后撤销 t p 和 _t 8, } Destructor Called. // 撤消对象 p2 6, 13 8intDestructor main( ) Called. // 撤消对象 p1 14 { 15 Point p1(6, 8), p2; 16 p2 = move(p1, 2, 4); // A, B 对象为函数参数, 用实参对象初始化形参对象 return 0; 19 } 此程序运行结果是? 不同编译器对返回的处理方式不同, 输出结果因而不同 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

37 程序运行结果 VS2017 拷贝构造函数 拷贝构造函数的调用时机 6, 8 Copy-initialization Constructor Called. // A 8, 12 Copy-initialization Constructor Called. // B 创建临时对象 8, 理解拷贝构造函数的用法 12 Destructor Called., 注意拷贝构造函数的调用时机 // 撤消对象 t 6, 8 Destructor Called. // 撤消对象 p 1 #include <iostream> 8, 12 2 #include Destructor "./Point.h" Called. // 撤消临时对象 8, 3 12 using Destructor namespace std; Called. // 撤消对象 p2 6, 4 8 Destructor Called. // 撤消对象 p1 5 // 注意 :move 是普通函数, 不是类的成员函数 6 Point move(point p, int xoffset, int yoffset) // A Point p=p1 参数传递程序运行结果 GCC { 6, 8 8 Copy-initialization int x = p.getx( )+xoffset; Constructor Called. // A 9 8, 12 Destructor int y = p.gety( Called. )+yoffset; // 撤消对象 t 10 Point t(x, y); 6, 8 Destructor 11 return t; // Called. B 返回时创建临时对象 // 撤消对象 _t 调用拷贝构造 p ; 先后撤销 t p 和 _t 8, } Destructor Called. // 撤消对象 p2 6, 13 8intDestructor main( ) Called. // 撤消对象 p1 14 { 15 Point p1(6, 8), p2; 临时对象 如果函数返回值是一个对象 16 p2 = move(p1, 2, 4); // A, B 对象为函数参数, 用实参对象初始化形参对象 17 在 return t 时编译器悄悄地 调用拷贝构造函数为局部对象 t 创建临时对象 18 (t 的副本 return_t), 0; 从而将局部对象拷贝到外部存储器 ; 19 } 在撤销对象时, 编译器先撤销函数内部的局部对象 t 和 p 后撤销被拷贝到此程序运行结果是外部存储器中的临时对象? 不同编译器对返回的处理方式不同 _t, 输出结果因而不同 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

38 提纲 构造函数与类型转换 1 拷贝构造函数 2 构造函数与类型转换 3 构造函数与对象成员 4 对象成员的初始化 5 总结与思考 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

39 构造函数与类型转换利用构造函数进行类型转换 C++ 不同内置类型的变量之间可以相互赋值 1 double a = ; 2 int b = (int)a; 1 string str="abc"; 2 char *p=str.data(); Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

40 构造函数与类型转换利用构造函数进行类型转换 C++ 不同内置类型的变量之间可以相互赋值 1 double a = ; 2 int b = (int)a; 1 string str="abc"; 2 char *p=str.data(); 问题 : 如果有自定义类型 复数类的对象 Complex c;, 能否执行 c = 5.0;, 即 : 将 5.0 做为实部,0 做为虚部的一个复数赋值给复数 c Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

41 构造函数与类型转换利用构造函数进行类型转换 C++ 不同内置类型的变量之间可以相互赋值 1 double a = ; 2 int b = (int)a; 1 string str="abc"; 2 char *p=str.data(); 问题 : 如果有自定义类型 复数类的对象 Complex c;, 能否执行 c = 5.0;, 即 : 将 5.0 做为实部,0 做为虚部的一个复数赋值给复数 c C++ 不同自定义类型的变量之间也可以相互赋值 C++ 当时的设计目标之一就是 : 自定义类型要和内置类型有具同等地位 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

42 构造函数与类型转换利用构造函数进行类型转换 C++ 不同内置类型的变量之间可以相互赋值 1 double a = ; 2 int b = (int)a; 1 string str="abc"; 2 char *p=str.data(); 问题 : 如果有自定义类型 复数类的对象 Complex c;, 能否执行 c = 5.0;, 即 : 将 5.0 做为实部,0 做为虚部的一个复数赋值给复数 c C++ 不同自定义类型的变量之间也可以相互赋值 C++ 当时的设计目标之一就是 : 自定义类型要和内置类型有具同等地位 内置类型 vs 自定义类型 地位相同 : 内置类型支持的性能自定义类型也应该支持 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

43 构造函数与类型转换利用构造函数进行类型转换 C++ 不同内置类型的变量之间可以相互赋值 1 double a = ; 2 int b = (int)a; 1 string str="abc"; 2 char *p=str.data(); 问题 : 如果有自定义类型 复数类的对象 Complex c;, 能否执行 c = 5.0;, 即 : 将 5.0 做为实部,0 做为虚部的一个复数赋值给复数 c C++ 不同自定义类型的变量之间也可以相互赋值 C++ 当时的设计目标之一就是 : 自定义类型要和内置类型有具同等地位 内置类型 vs 自定义类型 地位相同 : 内置类型支持的性能自定义类型也应该支持 答案 可以!!! 利用拷贝构造函数 形如 1 c = Complex(5.0); // 利用拷贝构造函数进行类型转换 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

44 构造函数与类型转换利用构造函数进行类型转换 类型转换, 完整程序代码如下 : 1 #include <iostream> 2 using namespace std; 3 4 class Complex 5 { 6 double Real, Image; 7 public: 8 Complex(double x=0, double y =0) 9 { 10 Real = x; 11 Image = y; 12 Show( ); 13 cout<<" 调用了构造函数 \n"; 14 } 15 ~Complex( ) 16 { 17 Show( ); 18 cout<<" 调用了析构函数 \n"; 19 } 20 void Show( ) 21 { 22 cout<< ( <<Real<<, << Image<< ) ; 23 } 24 }; 25 int main( ) 26 { 27 Complex c1(3, 5), c2; // A 28 c1 = 8.0; // B 等价于 c1 = Complex(8.0); 29 c2 = Complex(9.0, 9.0); // C 30 return 0; 31 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

45 构造函数与类型转换利用构造函数进行类型转换 类型转换, 完整程序代码如下 : 1 #include <iostream> 13 cout<<" 调用了构造函数 \n"; 程序运行结果 2 using namespace std; 14 } (3, 3 5) 调用了构造函数 // 在 A 行创建 c1 对象时 15, 调用构造函数 ~Complex( ) 4 class Complex 16 { (0, 0) 调用了构造函数 // 在 A 行创建 c2 对象时, 调用构造函数 5 { 17 Show( ); (8, 6 0) 调用了构造函数 double Real, Image; // 创建 撤消临时对象 18,B 行 cout<<" 调用了析构函数 \n"; (8, 7 public: 0) 调用了析构函数 // 创建 撤消临时对象 19,B} 行 8 Complex(double x=0, double y 20 (9, 9) 调用了构造函数 // 创建 撤消临时对象,C void 行 Show( ) =0) 21 { (9, 9) 调用了析构函数 // 创建 撤消临时对象,C 行 9 { 22 cout<< ( <<Real<<, << 10 (9, 9) 调用了析构函数 Real = x; // 在程序结束, 撤消 c2 对象时 Image<< ) ;, 调用析构函数 11 (8, 0) 调用了析构函数 Image = y; // 在程序结束, 撤消 23 c1 对象时 }, 调用析构函数 12 Show( ); 24 }; 25 int main( ) 26 { 27 Complex c1(3, 5), c2; // A 28 c1 = 8.0; // B 等价于 c1 = Complex(8.0); 29 c2 = Complex(9.0, 9.0); // C 30 return 0; 31 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

46 提纲 构造函数与对象成员 1 拷贝构造函数 2 构造函数与类型转换 3 构造函数与对象成员 4 对象成员的初始化 5 总结与思考 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

47 对象成员 构造函数与对象成员 对象成员 : 当一个类的成员是另一个类的对象时, 这个对象就叫对象成员, 也可称之为成员对象 概括的说, 就是一个类的成员是另一个类的对象 在创建新的类时, 经常将简单类的对象作为复杂类的对象成员 这个新类和对象成员之间的关系是 has-a ( 从属 ) 关系, 即 The new class has-a (or an) object 让我们举例说明这个问题 设计一个复杂类, 包含三个简单类的对象 例一简单类 :Wheel Motor Chair 复杂类 :Car 例二简单类 : 点 线段 复杂类 : 矩形 请描述这些类之间的逻辑关系, 并尝试编写伪代码 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

48 对象成员 构造函数与对象成员 对象成员 : 当一个类的成员是另一个类的对象时, 这个对象就叫对象成员, 也可称之为成员对象 概括的说, 就是一个类的成员是另一个类的对象 在创建新的类时, 经常将简单类的对象作为复杂类的对象成员 这个新类和对象成员之间的关系是 has-a ( 从属 ) 关系, 即 The new class has-a (or an) object 让我们举例说明这个问题 设计一个复杂类, 包含三个简单类的对象 例一简单类 :Wheel Motor Chair 复杂类 :Car 例二简单类 : 点 线段 复杂类 : 矩形 请描述这些类之间的逻辑关系, 并尝试编写伪代码 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

49 对象成员 构造函数与对象成员 对象成员 : 当一个类的成员是另一个类的对象时, 这个对象就叫对象成员, 也可称之为成员对象 概括的说, 就是一个类的成员是另一个类的对象 在创建新的类时, 经常将简单类的对象作为复杂类的对象成员 这个新类和对象成员之间的关系是 has-a ( 从属 ) 关系, 即 The new class has-a (or an) object 让我们举例说明这个问题 设计一个复杂类, 包含三个简单类的对象 例一简单类 :Wheel Motor Chair 复杂类 :Car 例二简单类 : 点 线段 复杂类 : 矩形 请描述这些类之间的逻辑关系, 并尝试编写伪代码 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

50 对象成员 构造函数与对象成员 对象成员 : 当一个类的成员是另一个类的对象时, 这个对象就叫对象成员, 也可称之为成员对象 概括的说, 就是一个类的成员是另一个类的对象 在创建新的类时, 经常将简单类的对象作为复杂类的对象成员 这个新类和对象成员之间的关系是 has-a ( 从属 ) 关系, 即 The new class has-a (or an) object 让我们举例说明这个问题 设计一个复杂类, 包含三个简单类的对象 例一简单类 :Wheel Motor Chair 复杂类 :Car 例二简单类 : 点 线段 复杂类 : 矩形 请描述这些类之间的逻辑关系, 并尝试编写伪代码 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

51 对象成员 构造函数与对象成员 对象成员 : 当一个类的成员是另一个类的对象时, 这个对象就叫对象成员, 也可称之为成员对象 概括的说, 就是一个类的成员是另一个类的对象 在创建新的类时, 经常将简单类的对象作为复杂类的对象成员 这个新类和对象成员之间的关系是 has-a ( 从属 ) 关系, 即 The new class has-a (or an) object 让我们举例说明这个问题 设计一个复杂类, 包含三个简单类的对象 例一简单类 :Wheel Motor Chair 复杂类 :Car 例二简单类 : 点 线段 复杂类 : 矩形 请描述这些类之间的逻辑关系, 并尝试编写伪代码 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

52 构造函数与对象成员程序 Rectangle.h 代码 1 #include <iostream> 2 class Point 3 { 4 public: 5 // no constructor, use default 6 void setx(int newx) { x = newx; } 7 void sety(int newy) { y = newy; } 8 int getx() const { return x;} 9 int gety() const { return y;} 10 private: 11 int x; int y; 12 }; 13 class Rectangle 14 { 15 public: 16 Rectangle(int newtop, int newleft, int newbottom, int newright); 17 ~Rectangle() {} int gettop() const { return top; } 20 int getleft() const { return left; } 21 int getbottom() const { return bottom; } 22 int getright() const { return right; } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

53 构造函数与对象成员程序 Rectangle.h 代码 23 Point getupperleft() const { return upperleft; } 24 Point getlowerleft() const { return lowerleft; } 25 Point getupperright() const { return upperright; } 26 Point getlowerright() const { return lowerright; } void setupperleft(point location); 29 void setlowerleft(point location); 30 void setupperright(point location); 31 void setlowerright(point location); void settop(int newtop); void setleft (int newleft); 34 void setbottom (int newbottom); void setright (int newright); int getarea() const; 37 private: 38 Point upperleft; Point upperright; 39 Point lowerleft; Point lowerright; 40 int top; int left; 41 int bottom; int right; 42 }; 请在 CodeBlocks 中测试 Rectangle.h Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

54 构造函数与对象成员程序 Rectangle.cpp 代码 1 #include "Rectangle.h" 2 3 Rectangle::Rectangle(int newtop, int newleft, int newbottom, int newright ) 4 { 5 top = newtop; 6 left = newleft; 7 bottom = newbottom; 8 right = newright; 9 10 upperleft.setx(left); 11 upperleft.sety(top); upperright.setx(right); 14 upperright.sety(top); lowerleft.setx(left); 17 lowerleft.sety(bottom); lowerright.setx(right); 20 lowerright.sety(bottom); 21 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

55 构造函数与对象成员程序 Rectangle.cpp 代码 void Rectangle::setUpperLeft(Point location) 24 { 25 upperleft = location; 26 upperright.sety(location.gety()); 27 lowerleft.setx(location.getx()); 28 top = location.gety(); 29 left = location.getx(); 30 } void Rectangle::setLowerLeft(Point location) 33 { 34 lowerleft = location; 35 lowerright.sety(location.gety()); 36 upperleft.setx(location.getx()); 37 bottom = location.gety(); 38 left = location.getx(); 39 } void Rectangle::setLowerRight(Point location) 42 { 43 lowerright = location; Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

56 构造函数与对象成员程序 Rectangle.cpp 代码 44 lowerleft.sety(location.gety()); 45 upperright.setx(location.getx()); 46 bottom = location.gety(); 47 right = location.getx(); 48 } void Rectangle::setUpperRight(Point location) 51 { 52 upperright = location; 53 upperleft.sety(location.gety()); 54 lowerright.setx(location.getx()); 55 top = location.gety(); 56 right = location.getx(); 57 } void Rectangle::setTop(int newtop) 60 { 61 top = newtop; 62 upperleft.sety(top); 63 upperright.sety(top); 64 } 65 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

57 构造函数与对象成员程序 Rectangle.cpp 代码 66 void Rectangle::setLeft(int newleft) 67 { 68 left = newleft; 69 upperleft.setx(left); 70 lowerleft.setx(left); 71 } void Rectangle::setBottom(int newbottom) 74 { 75 bottom = newbottom; 76 lowerleft.sety(bottom); 77 lowerright.sety(bottom); 78 } void Rectangle::setRight(int newright) 81 { 82 right = newright; 83 upperright.setx(right); 84 lowerright.setx(right); 85 } int Rectangle::getArea() const Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

58 构造函数与对象成员程序 Rectangle.cpp 代码 88 { 89 int width = right - left; 90 int height = top - bottom; 91 return (width * height); 92 } // compute area of the rectangle by finding corners, 95 // establish width and height and then multiply 96 int main() 97 { 98 // initialize a local Rectangle variable 99 Rectangle myrectangle(100, 20, 50, 80 ); int area = myrectangle.getarea(); std::cout << "Area: " << area << "\n"; 104 std::cout << "Upper Left X Coordinate: "; 105 std::cout << myrectangle.getupperleft().getx() << "\n"; 106 return 0; 107 } 请在 CodeBlocks 中测试 Rectangle.cpp Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

59 提纲 对象成员的初始化 1 拷贝构造函数 2 构造函数与类型转换 3 构造函数与对象成员 4 对象成员的初始化 5 总结与思考 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

60 对象成员的初始化对象成员的声明格式 在产生新定义类的对象时 必须对新定义类的对象成员进行初始化, 且只能通过新类的构造函数完成对其所有成员的初始化 初始化新类的对象时, 先调用对象成员的构造函数完成对象成员的初始化, 再调用对象自身的构造函数完成其他成员的初始化 对象销毁时, 析构函数的调用顺序与构造函数的调用顺序相反 在类的定义中, 声明对象成员的一般格式为 : 1 class ClassName 2 { 3 ClassName1 c1; // ClassName1-n 是已定义的类名 ClassNamen cn; 6 int x1,..., xn; // x1-xn 是内置类型的变量名 7 public: 8 ClassName(ArgsList) : c1 (arg1),..., cn (argn) 9 {...} }MyObject(ArgsList); Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

61 对象成员的初始化对象成员的声明格式 在产生新定义类的对象时 必须对新定义类的对象成员进行初始化, 且只能通过新类的构造函数完成对其所有成员的初始化 初始化新类的对象时, 先调用对象成员的构造函数完成对象成员的初始化, 再调用对象自身的构造函数完成其他成员的初始化 对象销毁时, 析构函数的调用顺序与构造函数的调用顺序相反 在类的定义中, 声明对象成员的一般格式为 : 1 class ClassName 2 { 3 ClassName1 c1; // ClassName1-n 是已定义的类名 ClassNamen cn; 6 int x1,..., xn; // x1-xn 是内置类型的变量名 7 public: 8 ClassName(ArgsList) : c1 (arg1),..., cn (argn) 9 {...} }MyObject(ArgsList); Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

62 对象成员的初始化对象成员的声明格式 在产生新定义类的对象时 必须对新定义类的对象成员进行初始化, 且只能通过新类的构造函数完成对其所有成员的初始化 初始化新类的对象时, 先调用对象成员的构造函数完成对象成员的初始化, 再调用对象自身的构造函数完成其他成员的初始化 对象销毁时, 析构函数的调用顺序与构造函数的调用顺序相反 在类的定义中, 声明对象成员的一般格式为 : 1 class ClassName 2 { 3 ClassName1 c1; // ClassName1-n 是已定义的类名 ClassNamen cn; 6 int x1,..., xn; // x1-xn 是内置类型的变量名 7 public: 8 ClassName(ArgsList) : c1 (arg1),..., cn (argn) 9 {...} }MyObject(ArgsList); Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

63 对象成员的初始化对象成员的声明格式 在产生新定义类的对象时 必须对新定义类的对象成员进行初始化, 且只能通过新类的构造函数完成对其所有成员的初始化 初始化新类的对象时, 先调用对象成员的构造函数完成对象成员的初始化, 再调用对象自身的构造函数完成其他成员的初始化 对象销毁时, 析构函数的调用顺序与构造函数的调用顺序相反 在类的定义中, 声明对象成员的一般格式为 : 1 class ClassName 2 { 3 ClassName1 c1; // ClassName1-n 是已定义的类名 ClassNamen cn; 6 int x1,..., xn; // x1-xn 是内置类型的变量名 7 public: 8 ClassName(ArgsList) : c1 (arg1),..., cn (argn) 9 {...} }MyObject(ArgsList); Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

64 对象成员的初始化对象成员的声明格式 在产生新定义类的对象时 必须对新定义类的对象成员进行初始化, 且只能通过新类的构造函数完成对其所有成员的初始化 初始化新类的对象时, 先调用对象成员的构造函数完成对象成员的初始化, 再调用对象自身的构造函数完成其他成员的初始化 对象销毁时, 析构函数的调用顺序与构造函数的调用顺序相反 在类的定义中, 声明对象成员的一般格式为 : 1 class ClassName 2 { 3 ClassName1 c1; // ClassName1-n 是已定义的类名 ClassNamen cn; 6 int x1,..., xn; // x1-xn 是内置类型的变量名 7 public: 8 ClassName(ArgsList) : c1 (arg1),..., cn (argn) 9 {...} }MyObject(ArgsList); Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

65 对象成员的初始化对象成员的初始化列表 ArgsList 中的形参必须带有类型说明, 而 arg1,...,argn 是实参, 不需要类型说明, 它们可以是来自于 ArgsList 的变量, 也可以是常量 表达式或其他形式 请思考 : 为什么 arg1,...,argn 不需要类型说明? 对象成员构造函数的调用顺序由对象成员的定义顺序决定 ( 先定义者先被调用 ), 而与成员在初始化列表中的顺序无关 请思考 : 为什么与写在成员初始化列表中的顺序无关, 而与对象成员的定义顺序有关? 原因是 : Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

66 对象成员的初始化对象成员的初始化列表 ArgsList 中的形参必须带有类型说明, 而 arg1,...,argn 是实参, 不需要类型说明, 它们可以是来自于 ArgsList 的变量, 也可以是常量 表达式或其他形式 请思考 : 为什么 arg1,...,argn 不需要类型说明? 对象成员构造函数的调用顺序由对象成员的定义顺序决定 ( 先定义者先被调用 ), 而与成员在初始化列表中的顺序无关 请思考 : 为什么与写在成员初始化列表中的顺序无关, 而与对象成员的定义顺序有关? 原因是 : Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

67 对象成员的初始化对象成员的初始化列表 ArgsList 中的形参必须带有类型说明, 而 arg1,...,argn 是实参, 不需要类型说明, 它们可以是来自于 ArgsList 的变量, 也可以是常量 表达式或其他形式 请思考 : 为什么 arg1,...,argn 不需要类型说明? 原因是 : 1 参数 arg1,...,argn 为已声明过的实参, 所以不需要类型说明 对象成员构造函数的调用顺序由对象成员的定义顺序决定 ( 先定义者先被调用 ), 而与成员在初始化列表中的顺序无关 请思考 : 为什么与写在成员初始化列表中的顺序无关, 而与对象成员的定义顺序有关? 原因是 : Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

68 对象成员的初始化对象成员的初始化列表 ArgsList 中的形参必须带有类型说明, 而 arg1,...,argn 是实参, 不需要类型说明, 它们可以是来自于 ArgsList 的变量, 也可以是常量 表达式或其他形式 请思考 : 为什么 arg1,...,argn 不需要类型说明? 原因是 : 1 参数 arg1,...,argn 为已声明过的实参, 所以不需要类型说明 对象成员构造函数的调用顺序由对象成员的定义顺序决定 ( 先定义者先被调用 ), 而与成员在初始化列表中的顺序无关 请思考 : 为什么与写在成员初始化列表中的顺序无关, 而与对象成员的定义顺序有关? 原因是 : Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

69 对象成员的初始化对象成员的初始化列表 ArgsList 中的形参必须带有类型说明, 而 arg1,...,argn 是实参, 不需要类型说明, 它们可以是来自于 ArgsList 的变量, 也可以是常量 表达式或其他形式 请思考 : 为什么 arg1,...,argn 不需要类型说明? 原因是 : 1 参数 arg1,...,argn 为已声明过的实参, 所以不需要类型说明 对象成员构造函数的调用顺序由对象成员的定义顺序决定 ( 先定义者先被调用 ), 而与成员在初始化列表中的顺序无关 请思考 : 为什么与写在成员初始化列表中的顺序无关, 而与对象成员的定义顺序有关? 原因是 : Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

70 对象成员的初始化对象成员的初始化列表 ArgsList 中的形参必须带有类型说明, 而 arg1,...,argn 是实参, 不需要类型说明, 它们可以是来自于 ArgsList 的变量, 也可以是常量 表达式或其他形式 请思考 : 为什么 arg1,...,argn 不需要类型说明? 原因是 : 1 参数 arg1,...,argn 为已声明过的实参, 所以不需要类型说明 对象成员构造函数的调用顺序由对象成员的定义顺序决定 ( 先定义者先被调用 ), 而与成员在初始化列表中的顺序无关 请思考 : 为什么与写在成员初始化列表中的顺序无关, 而与对象成员的定义顺序有关? 原因是 : 1 类的声明是唯一的, 而类构造函数可以有很多, 对象成员在不同初始化列表中的次序并不一定完全相同 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

71 对象成员的初始化对象成员的初始化列表 ArgsList 中的形参必须带有类型说明, 而 arg1,...,argn 是实参, 不需要类型说明, 它们可以是来自于 ArgsList 的变量, 也可以是常量 表达式或其他形式 请思考 : 为什么 arg1,...,argn 不需要类型说明? 原因是 : 1 参数 arg1,...,argn 为已声明过的实参, 所以不需要类型说明 对象成员构造函数的调用顺序由对象成员的定义顺序决定 ( 先定义者先被调用 ), 而与成员在初始化列表中的顺序无关 请思考 : 为什么与写在成员初始化列表中的顺序无关, 而与对象成员的定义顺序有关? 原因是 : 1 类的声明是唯一的, 而类构造函数可以有很多, 对象成员在不同初始化列表中的次序并不一定完全相同 2 如果对象成员按照它们在初始化表中的次序进行构造, 这将导致析构函数无法得到唯一的逆序, 也难以得到合理的逆序 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

72 对象成员的初始化对象成员的初始化列表 ArgsList 中的形参必须带有类型说明, 而 arg1,...,argn 是实参, 不需要类型说明, 它们可以是来自于 ArgsList 的变量, 也可以是常量 表达式或其他形式 请思考 : 为什么 arg1,...,argn 不需要类型说明? 原因是 : 1 参数 arg1,...,argn 为已声明过的实参, 所以不需要类型说明 对象成员构造函数的调用顺序由对象成员的定义顺序决定 ( 先定义者先被调用 ), 而与成员在初始化列表中的顺序无关 请思考 : 为什么与写在成员初始化列表中的顺序无关, 而与对象成员的定义顺序有关? 原因是 : 1 类的声明是唯一的, 而类构造函数可以有很多, 对象成员在不同初始化列表中的次序并不一定完全相同 2 如果对象成员按照它们在初始化表中的次序进行构造, 这将导致析构函数无法得到唯一的逆序, 也难以得到合理的逆序 3 如果对象成员按照初始化表进行构造, 则必须追踪初始化列表中成员的顺序才能得到合理的逆序 现在则节省了追踪初始化列表中成员顺序的成本 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

73 对象成员的初始化对象成员的初始化列表 如将程序 PointObjectInLine 中的 A 行 1 Line(int x1, int y1, int x2, int y2, int w, int c) : p1(x1,y1), p2(x2,y2) 改写为 1 Line(int x1, int y1, int x2, int y2, int w, int c) : p2(x2,y2), p1(x1,y1) 仍然是先调用 p1(x1, y1) 后调用 p2(x2, y2) 这是因为: Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

74 对象成员的初始化对象成员的初始化列表 如将程序 PointObjectInLine 中的 A 行 1 Line(int x1, int y1, int x2, int y2, int w, int c) : p1(x1,y1), p2(x2,y2) 改写为 1 Line(int x1, int y1, int x2, int y2, int w, int c) : p2(x2,y2), p1(x1,y1) 仍然是先调用 p1(x1, y1) 后调用 p2(x2, y2) 这是因为 : 1 对象成员构造函数的顺序由对象成员的定义顺序决定, 先定义者先被调用 2 由于 p1 的定义在前,p2 的定义在后, 所以先调用 p1(x1, y1) 后调用 p2(x2, y2) Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

75 对象成员的初始化对象成员的初始化列表 如将程序 PointObjectInLine 中的 A 行 1 Line(int x1, int y1, int x2, int y2, int w, int c) : p1(x1,y1), p2(x2,y2) 改写为 1 Line(int x1, int y1, int x2, int y2, int w, int c) : p2(x2,y2), p1(x1,y1) 仍然是先调用 p1(x1, y1) 后调用 p2(x2, y2) 这是因为 : 1 对象成员构造函数的顺序由对象成员的定义顺序决定, 先定义者先被调用 2 由于 p1 的定义在前,p2 的定义在后, 所以先调用 p1(x1, y1) 后调用 p2(x2, y2) 以下三种情况下需要使用初始化成员列表 需要初始化的数据成员是另一个类的对象, 即对象成员 需要初始化 const 修饰的数据成员或引用类型的数据成员 需要由派生 ( 子 ) 类初始化基 ( 父 ) 类的私有数据成员 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

76 对象成员的初始化使用初始化列表的情形 第一种情况 : 数据成员是对象, 并且这个对象只有带参数的构造函数, 没有默认构造函数 第二种情况 : 类的成员是引用类型或者是被 const 修饰的数据成员 第三种情况 : 派生 ( 子 ) 类初始化基 ( 父 ) 类的私有成员 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

77 对象成员的初始化使用初始化列表的情形 第一种情况 : 数据成员是对象, 并且这个对象只有带参数的构造函数, 没有默认构造函数 如果类的某个成员是另一个类 ( 或结构体 ) 的对象, 而且这个成员它只有一个带参数的构造函数, 而没有默认构造函数, 那么对这个成员进行初始化时, 就必须调用这个成员带参数的构造函数 如果没有初始化列表, 将无法完成对象初始化的第一步 ( 数据成员的初始化 ), 就会报错 第二种情况 : 类的成员是引用类型或者是被 const 修饰的数据成员 当类成员中含有一个 const 对象时, 或者是一个引用时, 也必须通过成员初始化列表进行初始化 这是因为, 这两种对象要在声明后马上初始化, 否则就要在构造函数中对它们赋值 ( 然而, 这是不允许的 ) 第三种情况 : 派生 ( 子 ) 类初始化基 ( 父 ) 类的私有成员 当派生类初始化基类的私有成员时, 需要在 ( 并且也只能在 ) 参数初始化列表中显式地调用基类的构造函数 在 继承与派生 章节对此详细介绍 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

78 对象成员的初始化使用初始化列表的情形 第一种情况 : 数据成员是对象, 并且这个对象只有带参数的构造函数, 没有默认构造函数 如果类的某个成员是另一个类 ( 或结构体 ) 的对象, 而且这个成员它只有一个带参数的构造函数, 而没有默认构造函数, 那么对这个成员进行初始化时, 就必须调用这个成员带参数的构造函数 如果没有初始化列表, 将无法完成对象初始化的第一步 ( 数据成员的初始化 ), 就会报错 InitializeListCondition1.cpp 第二种情况 : 类的成员是引用类型或者是被 const 修饰的数据成员 当类成员中含有一个 const 对象时, 或者是一个引用时, 也必须通过成员初始化列表进行初始化 这是因为, 这两种对象要在声明后马上初始化, 否则就要在构造函数中对它们赋值 ( 然而, 这是不允许的 ) InitializeListCondition2.cpp 第三种情况 : 派生 ( 子 ) 类初始化基 ( 父 ) 类的私有成员 当派生类初始化基类的私有成员时, 需要在 ( 并且也只能在 ) 参数初始化列表中显式地调用基类的构造函数 在 继承与派生 章节对此详细介绍 InitializeListCondition3.cpp Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

79 对象成员的初始化关于初始化列表的说明 第一种情况 : 数据成员是对象, 并且这个对象只有带参数的构造函数, 没有默认构造函数 1 #include <iostream> 2 using namespace std; 3 // 定义一个类 4 class Test 5 { 6 public: 7 Test (int, int, int) 8 { 9 cout <<"Test"<<endl; 10 }; 11 private: 12 int x; 13 int y; 14 int z; 15 }; 程序输出结果 : 16 class Mytest 17 { 18 public: 19 Mytest():test(1,2,3)// 初始化 20 { 21 cout <<"Mytest"<<endl; 22 }; 23 private: 24 Test test; // 声明 25 }; 26 int main(int argc, char* argv[]) 27 { 28 Mytest test; 29 return 0; 30 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

80 对象成员的初始化关于初始化列表的说明 第一种情况 : 数据成员是对象, 并且这个对象只有带参数的构造函数, 没有默认构造函数 1 #include <iostream> 2 using namespace std; 3 // 定义一个类 4 class Test 5 { 6 public: 7 Test (int, int, int) 8 { 9 cout <<"Test"<<endl; 10 }; 11 private: 12 int x; 13 int y; 14 int z; 15 }; 程序输出结果 : Test Mytest 16 class Mytest 17 { 18 public: 19 Mytest():test(1,2,3)// 初始化 20 { 21 cout <<"Mytest"<<endl; 22 }; 23 private: 24 Test test; // 声明 25 }; 26 int main(int argc, char* argv[]) 27 { 28 Mytest test; 29 return 0; 30 } 构造函数调用顺序 : Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

81 对象成员的初始化关于初始化列表的说明 第一种情况 : 数据成员是对象, 并且这个对象只有带参数的构造函数, 没有默认构造函数 1 #include <iostream> 2 using namespace std; 3 // 定义一个类 4 class Test 5 { 6 public: 7 Test (int, int, int) 8 { 9 cout <<"Test"<<endl; 10 }; 11 private: 12 int x; 13 int y; 14 int z; 15 }; 程序输出结果 : Test Mytest 16 class Mytest 17 { 18 public: 19 Mytest():test(1,2,3)// 初始化 20 { 21 cout <<"Mytest"<<endl; 22 }; 23 private: 24 Test test; // 声明 25 }; 26 int main(int argc, char* argv[]) 27 { 28 Mytest test; 29 return 0; 30 } 构造函数调用顺序 : Test() Mytest() Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

82 对象成员的初始化关于初始化列表的说明 第二种情况 : 类的成员是引用类型或者是被 const 修饰的数据成员 1 class Test 2 { 3 priate: 4 const int a; //const 成员的声明 5 public: 6 Test():a(10) {} // 初始化 7 }; 或 1 class Test 2 { 3 private: 4 int &a; // 引用的声明 5 public: 6 Test(int x):a(x) {} // 初始化 7 } 当类成员中含有一个 const 对象或一个引用时, 也必须通过初始化列表进行初始化, 不允许在构造函数中对它们赋值 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

83 对象成员的初始化关于初始化列表的说明 第三种情况 : 派生 ( 子 ) 类初始化基 ( 父 ) 类的私有成员 ( 暂不详述 ) 1 #include "iostream" 2 using namespace std; 3 class Test 4 { 5 public: 6 Test() { } 7 Test(int x) 8 { 9 int_x = x; 10 } 11 void show() 12 { 13 cout<< int_x << endl; 14 } 15 private: 16 int int_x; 17 }; 1 class Mytest : public Test 2 { 3 public: 4 Mytest() : Test(110) 5 { 6 //Test(110); // 构造函数只能在初始化列表中被显式调用, 不能在构造函数内部被显示调用, 如果无注释符则错 7 }; 8 }; 9 int main(int argc, char* argv[]) 10 { 11 Test *p = new Mytest(); 12 p->show(); 13 return 0; 14 } 当派生类初始化基类的私有成员时, 需要在并且也只能在参数初始化列表中显式调用基类的构造函数 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

84 对象成员的初始化对象数组与对象成员 扩充 : 对象数组, 栈中实例化和堆中实例化 1 class Coordinate 2 { 3 public: 4 int m_x; 5 int m_y; 6 }; 7 int main() 8 { 9 Coordinate coord[3]; // 栈中实例化 10 coord[1].m_x = 10; 11 Coordinate * p = new Coordinate[3]; // 堆中实例化 12 p[0].m_y = 20; // p->m_y = delete [] p; 14 p = NULL; 15 return 0; 16 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

85 对象成员的初始化对象数组与对象成员 扩充 : 对象数组, 栈中实例化和堆中实例化 1 class Coordinate 2 { 3 public: 4 int m_x; 5 int m_y; 6 }; 7 int main() 8 { 9 Coordinate coord[3]; // 栈中实例化 10 coord[1].m_x = 10; 11 Coordinate * p = new Coordinate[3]; // 堆中实例化 12 p[0].m_y = 20; // p->m_y = delete [] p; 14 p = NULL; 15 return 0; 16 } 在使用 new 申请数组空间后, 就要用 delete [] p 来释放内存 申请对象数组时调用了 n 次构造函数, 在释放时就要调用 n 次析构函数 如果忘掉 [], 那么只销毁指向指针的第一个元素 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

86 对象成员的初始化对象数组与对象成员 扩充 : 对象成员 ( 对象包含对象 ) 的实例化 1 class Coordinate // 坐标系上的点 2 { 3 public: 4 Coordinate(){ } 5 private: 6 int m_x; int m_y; 7 }; 8 class Line // 坐标系上的线 9 { 10 public: 11 Line(){ } 12 private: 13 Coordinate m_a; Coordinate m_b; 14 }; 15 int main() 16 { 17 Line *p = new Line(); delete p; p = NULL; return 0; 18 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

87 对象成员的初始化对象数组与对象成员 扩充 : 对象成员 ( 对象包含对象 ) 的实例化 1 class Coordinate // 坐标系上的点 2 { 3 public: 4 Coordinate(){ } 5 private: 6 int m_x; int m_y; 7 }; 8 class Line // 坐标系上的线 9 { 10 public: 11 Line(){ } 12 private: 13 Coordinate m_a; Coordinate m_b; 14 }; 15 int main() 16 { 17 Line *p = new Line(); delete p; p = NULL; return 0; 18 } 在实例化线的时, 先实例化 A 点, 其次实例化 B 点, 最后实例化线 ; 对象成员销毁的过程与对象成员创建的过程正好相反 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

88 深拷贝和浅拷贝 对象成员的初始化 扩充 : 拷贝构造函数之浅拷贝, 正确的代码 1 class Array 2 { 3 public: 4 Array() 5 { m_icount=5; } 6 Array(const Array & arr) 7 { m_icount=arr.m_icount; } 8 private: 8 int m_icount; 9 }; 10 int main() 11 { 12 Array arr1; 13 Array arr2=arr1; 14 return 0; 15 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

89 浅拷贝和深拷贝 对象成员的初始化 扩充 : 拷贝构造函数之浅拷贝, 错误的代码 1 class Array{ 2 public: 3 Array(){ m_icount=5; m_parr=new int[m_icount]; } 4 Array(const Array & arr)// 浅拷贝 5 { m_icounta = arr.m_icount; 6 m_parr = arr.m_parr; } 7 private: 9 int m_icount; 10 int * m_parr; // 指针 11 }; 12 int main(){ 13 Array arr1; 14 Array arr2=arr1;// 浅拷贝 15 return 0; 16 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

90 浅拷贝和深拷贝 对象成员的初始化 扩充 : 拷贝构造函数之浅拷贝, 错误的代码 ( 应采用深拷贝 ) 1 class Array{ 2 public: 3 Array(){ m_icount=5; m_parr=new int[m_icount]; } 4 Array(const Array & arr)// 浅拷贝 5 { m_icounta = arr.m_icount; 6 m_parr = arr.m_parr; } 7 private: 9 int m_icount; 10 int * m_parr; // 指针 11 }; 12 int main(){ 13 Array arr1; 14 Array arr2=arr1;// 浅拷贝 15 return 0; 16 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

91 浅拷贝和深拷贝 对象成员的初始化 扩充 : 拷贝构造函数之深拷贝, 正确的代码 ( 涉及动态内存 ) 1 class Array 2 { 3 public: 4 Array(){ m_icount=5; m_parr=new int[m_icount]; } 5 Array(const Array & arr)// 深拷贝 6 { 7 m_icounta = arr.m_icount; 8 m_parr = new int[m_icount]; 9 for(int i=0; i < m_icount; i++) 10 { m_parr[i] = arr.m_parr[i]; } 9 } 10 private: 11 int m_icount; 12 int * m_parr; // 指针 13 }; 14 int main() 15 { 16 Array arr1; 17 Array arr2=arr1;// 深拷贝 18 return 0; 19 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

92 提纲 总结与思考 1 拷贝构造函数 2 构造函数与类型转换 3 构造函数与对象成员 4 对象成员的初始化 5 总结与思考 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

93 总结与思考 总结与思考 什么是拷贝构造函数? 它有什么作用? 调用拷贝构造函数发生在什么时机? 有哪几种情况? 编译器会生成默认的拷贝构造函数吗? Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

94 总结与思考 总结与思考 什么是拷贝构造函数? 它有什么作用? 拷贝构造函数是一种特殊的构造函数, 用来完成一些基于同一类的非当前对象的构建及初始化 调用拷贝构造函数发生在什么时机? 有哪几种情况? 编译器会生成默认的拷贝构造函数吗? Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

95 总结与思考 总结与思考 什么是拷贝构造函数? 它有什么作用? 拷贝构造函数是一种特殊的构造函数, 用来完成一些基于同一类的非当前对象的构建及初始化 调用拷贝构造函数发生在什么时机? 有哪几种情况? 三种情况 : 一个对象以值传递的方式传入函数体 ; 一个对象以值传递的方式从函数返回 ; 一个对象需要通过另一个对象进行初始化 编译器会生成默认的拷贝构造函数吗? Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

96 总结与思考 总结与思考 什么是拷贝构造函数? 它有什么作用? 拷贝构造函数是一种特殊的构造函数, 用来完成一些基于同一类的非当前对象的构建及初始化 调用拷贝构造函数发生在什么时机? 有哪几种情况? 三种情况 : 一个对象以值传递的方式传入函数体 ; 一个对象以值传递的方式从函数返回 ; 一个对象需要通过另一个对象进行初始化 编译器会生成默认的拷贝构造函数吗? 1 如果用户没有自定义拷贝构造函数, 并且在代码中使用到了拷贝构造函数, 编译器就会生成默认的拷贝构造函数 2 如果用户定义了一个构造函数, 但不是拷贝构造函数, 而此时代码中又用到了拷贝构造函数, 那编译器也会生成默认的拷贝构造函数 3 如果用户定义了拷贝构造函数, 编译器就不会生成默认的拷贝构造函数 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

97 总结与思考 总结与思考 问题一 : 写出下列程序输出结果 1 class CopyCons 2 { 3 public: 4 CopyCons(int i,int j,int k) 5 { 6 a = i; b = j; c = k; 7 cout << " 有参构 造 " << i << \n ; 8 } 9 ~CopyCons() 10 { cout << " 对象析构 \n"; } 11 int getc() 12 { return a; } 13 private: 14 int a,b,c; 15 }; 16 class Test 17 { 18 public: 19 Test():p(1,2,3),q(4,5,6),x(7) 20 { cout << " 构造 Test\n"; } 21 ~Test() 22 { cout << " 析构 Test\n"; } 23 Test(const Test &obj):p (8,9,10),q(11,12,13),x(14) 24 { cout << " 拷贝构造 \n"; } 25 CopyCons p, q; // 注意 26 int x; 27 }; 28 void show(test mytest) 29 { 30 cout << " 我的测试 " << mytest.p.getc()<<endl; 31 } 32 int main() 33 { 34 Test mytest; 35 show(mytest); 36 return 0; 37 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

98 总结与思考 总结与思考 程序输出结果是 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

99 总结与思考 总结与思考 问题二 : 写出下列程序输出结果 1 class CopyCons 2 { 3 public: 4 CopyCons(int i,int j,int k) 5 { 6 a = i; b = j; c = k; 7 cout << " 有参构 造 " << i << \n ; 8 } 9 ~CopyCons() 10 { cout << " 对象析构 \n"; } 11 int getc() 12 { return a; } 13 private: 14 int a,b,c; 15 }; 16 class Test 17 { 18 public: 19 Test():p(1,2,3),q(4,5,6),x(7) 20 { cout << " 构造 Test\n"; } 21 ~Test() 22 { cout << " 析构 Test\n"; } 23 Test(const Test &obj):p (8,9,10),q(11,12,13),x(14) 24 { cout << " 拷贝构造 \n"; } 25 CopyCons q, p; // 注意 26 int x; 27 }; 28 void show(test mytest) 29 { 30 cout << " 我的测试 " << mytest.p.getc()<<endl; 31 } 32 int main() 33 { 34 Test mytest; 35 show(mytest); 36 return 0; 37 } Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

100 总结与思考 总结与思考 程序输出结果是 Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

101 总结与思考 作业 总结与思考 选择题 1 下列说法中错误的是 a a a a a A) 如果用户不定义缺省构造函数, 则系统自动生成一个缺省构造函数 B) 如果用户不定义拷贝构造函数, 则系统自动生成一个拷贝构造函数 C) 如果用户不定义析构函数, 则系统自动生成一个默认的析构函数 D) 如果用户定义了析构函数, 则系统就不会自动生成任何析构函数 2 下列说法中正确的是 a a a a a A) 类与对象的关系就是数据类型与变量的关系 B) 对象是类的一个实例 C) 任何一个对象必定属于一个特定的类 D) 一个类只能有一个对象 E) 类的普通成员函数可以设置参数的缺省值 F) 类的静态成员函数不能声明为类的内联函数 G) 声明为内联的成员函数一定可以减少调用开销 简答题 3 什么是拷贝构造函数? 拷贝构造函数用于哪三个方面? Dongke Sun (Southeast University) C++ Programming and Algorithms Spring semester, / 51

エスポラージュ株式会社 住所 : 東京都江東区大島 東急ドエルアルス大島 HP: ******************* * 关于 Java 测试试题 ******

エスポラージュ株式会社 住所 : 東京都江東区大島 東急ドエルアルス大島 HP:  ******************* * 关于 Java 测试试题 ****** ******************* * 关于 Java 测试试题 ******************* 問 1 运行下面的程序, 选出一个正确的运行结果 public class Sample { public static void main(string[] args) { int[] test = { 1, 2, 3, 4, 5 ; for(int i = 1 ; i System.out.print(test[i]);

More information

Microsoft PowerPoint - 8. 运算符重载 Operator Overloading.pptx

Microsoft PowerPoint - 8. 运算符重载 Operator Overloading.pptx 运算符重载 Operator Overloading class Point { public: ; double x_, y_; Why Operator Overloading? Point (double x =0, double y = 0):x_(x),y_(y) { int main(){ Point a(1., 2), b(3,4); Point c = a + b; return 0;

More information

Microsoft Word - 新1-12.doc

Microsoft Word - 新1-12.doc 实训 5 面向对象编程练习 实训 5 面向对象编程练习 5.1 实训目的 通过编程和上机实验理解 Java 语言是如何体现面向对象编程基本思想 以及如何创建类 和对象 了解成员变量和成员方法的特性 5.2 实训要求 编写一个体现面向对象思想的程序 编写一个创建对象和使用对象的方法的程序 5.3 实训内容 5.3.1 创建对象并使用对象 1 定义一个 Person 类 可以在应用程序中使用该类 成员属性

More information

Microsoft PowerPoint - 6. 用户定义类型User-defined Datatypes.ppt [兼容模式]

Microsoft PowerPoint - 6. 用户定义类型User-defined Datatypes.ppt [兼容模式] 用户定义类型 User-defined Datatypes classes and structs 几何向量 (Geometry Vector) 二维平面上的向量由起点和终点构成 每个点包含两个坐标 (x, y), 因此一个向量需要四个实数表示 Start= (0.9,1.5) Start= (0.4,0.8) int main() { double xstart = 0.4; double xend

More information

C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1

C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1 C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 月 3 日 1 1 INPUTOUTPUT 1 InputOutput 题目描述 用 cin 输入你的姓名 ( 没有空格 ) 和年龄 ( 整数 ), 并用 cout 输出 输入输出符合以下范例 输入 master 999 输出 I am master, 999 years old. 注意 "," 后面有一个空格,"." 结束,

More information

程序设计语言及基础

程序设计语言及基础 Chapter 10 Classes: A Deeper Look, Part 2 http://jssec.seu.edu.cn 杨明 yangming2002@seu.edu.cn OBJECTIVES To specify const (constant) objects and const member functions. To create objects composed of other

More information

c_cpp

c_cpp C C++ C C++ C++ (object oriented) C C++.cpp C C++ C C++ : for (int i=0;i

More information

C++ 程序设计 OJ2 - 参考答案 MASTER 2019 年 5 月 3 日 1

C++ 程序设计 OJ2 - 参考答案 MASTER 2019 年 5 月 3 日 1 C++ 程序设计 OJ2 - 参考答案 MASTER 2019 年 5 月 3 日 1 1 PERSON 1 Person 题目描述 编写程序, 定义一个基类 Person, 包含 name 和 age 两个数据成员 ; 再由它派生出学生类 Student 和教师类 Teacher, 其中学生类添加学号 no 数据, 教师类添加职称 title 数据 ; 要求每个类均有构造函数 析构函数和显示数据的函数

More information

第3章.doc

第3章.doc 3 3 3 3.1 3 IT Trend C++ Java SAP Advantech ERPCRM C++ C++ Synopsys C++ NEC C C++PHP C++Java C++Java VIA C++ 3COM C++ SPSS C++ Sybase C++LinuxUNIX Motorola C++ IBM C++Java Oracle Java HP C++ C++ Yahoo

More information

C++ 程序设计 告别 OJ2 - 参考答案 MASTER 2019 年 5 月 3 日 1

C++ 程序设计 告别 OJ2 - 参考答案 MASTER 2019 年 5 月 3 日 1 C++ 程序设计 告别 OJ2 - 参考答案 MASTER 2019 年 5 月 3 日 1 1 TEMPLATE 1 Template 描述 使用模板函数求最大值 使用如下 main 函数对程序进行测试 int main() { double a, b; cin >> a >> b; cout c >> d; cout

More information

OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课

OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课 复习 Java 包 创建包 : package 语句, 包结构与目录结构一致 使用包 : import restaurant/ - people/ - Cook.class - Waiter.class - tools/ - Fork.class

More information

C/C++程序设计 - 字符串与格式化输入/输出

C/C++程序设计 - 字符串与格式化输入/输出 C/C++ / Table of contents 1. 2. 3. 4. 1 i # include # include // density of human body : 1. 04 e3 kg / m ^3 # define DENSITY 1. 04 e3 int main ( void ) { float weight, volume ; int

More information

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double

More information

Microsoft PowerPoint - 10 模板 Template.pptx

Microsoft PowerPoint - 10 模板 Template.pptx 模板 Tempalte 泛型编程的需要 Why Templates? 设想你对整数类型实现了一个排序算法 : void sort(int *is,int n); 用该函数可以对实 复数或工资单排序吗? 模板可以复用源代码 - 泛型编程. inline void Swap( int &x, int &y){ int t = x; x = y; y =t; inline void Swap(double

More information

OOP with Java 通知 Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢 学习使用文本编辑器 学习使用 cmd: Power shell 阅读参考资料

OOP with Java 通知 Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢   学习使用文本编辑器 学习使用 cmd: Power shell 阅读参考资料 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢 Email: 51141201063@ecnu.cn 学习使用文本编辑器 学习使用 cmd: Power shell 阅读参考资料 OOP with Java Java 类型 引用 不可变类型 对象存储位置 作用域 OOP

More information

Microsoft PowerPoint - string_kruse [兼容模式]

Microsoft PowerPoint - string_kruse [兼容模式] Strings Strings in C not encapsulated Every C-string has type char *. Hence, a C-string references an address in memory, the first of a contiguous set of bytes that store the characters making up the string.

More information

第七讲 继承与多态

第七讲  继承与多态 第 七 章 继 承 与 派 生 1 本 章 主 要 内 容 的 继 承 成 员 的 访 问 控 制 单 继 承 与 多 继 承 派 生 的 构 造 析 构 函 数 成 员 的 标 识 与 访 问 深 度 探 索 2 的 继 承 与 派 生 的 继 承 与 派 生 保 持 已 有 的 特 性 而 构 造 新 的 过 程 称 为 继 承 在 已 有 的 基 础 上 新 增 自 己 的 特 性 而 产 生

More information

NOWOER.OM m/n m/=n m/n m%=n m%n m%=n m%n m/=n 4. enum string x1, x2, x3=10, x4, x5, x; 函数外部问 x 等于什么? 随机值 5. unsigned char *p1; unsigned long *p

NOWOER.OM m/n m/=n m/n m%=n m%n m%=n m%n m/=n 4. enum string x1, x2, x3=10, x4, x5, x; 函数外部问 x 等于什么? 随机值 5. unsigned char *p1; unsigned long *p NOWOER.OM /++ 程师能 评估. 单项选择题 1. 下 描述正确的是 int *p1 = new int[10]; int *p2 = new int[10](); p1 和 p2 申请的空间 的值都是随机值 p1 和 p2 申请的空间 的值都已经初始化 p1 申请的空间 的值是随机值,p2 申请的空间 的值已经初始化 p1 申请的空间 的值已经初始化,p2 申请的空间 的值是随机值 2.

More information

C++ 程序设计 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1

C++ 程序设计 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1 C++ 程序设计 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1 1 CIRCLE 1 Circle 描述 编写一个圆类 Circle, 实现半径的输入 面积的计算和输出 输入 圆的半径 (double 类型 ) 输出 圆的面积 ( 保留小数点后两位 ) 样例输入 3 样例输出 28.27 提示 圆周率的取值需要比较精确, 以保证计算结果的精度 #include

More information

Microsoft PowerPoint - L17_Inheritance_v4.pptx

Microsoft PowerPoint - L17_Inheritance_v4.pptx C++ Programming Lecture 17 Wei Liu ( 刘 威 ) Dept. of Electronics and Information Eng. Huazhong University of Science and Technology May. 2015 Lecture 17 Chapter 20. Object-Oriented Programming: Inheritance

More information

Strings

Strings Inheritance Cheng-Chin Chiang Relationships among Classes A 類 別 使 用 B 類 別 學 生 使 用 手 機 傳 遞 訊 息 公 司 使 用 金 庫 儲 存 重 要 文 件 人 類 使 用 交 通 工 具 旅 行 A 類 別 中 有 B 類 別 汽 車 有 輪 子 三 角 形 有 三 個 頂 點 電 腦 內 有 中 央 處 理 單 元 A

More information

C++ 程序设计 实验 3 - 参考答案 MASTER 2017 年 5 月 21 日 1

C++ 程序设计 实验 3 - 参考答案 MASTER 2017 年 5 月 21 日 1 C++ 程序设计 实验 3 - 参考答案 MASTER 2017 年 5 月 21 日 1 1 圆 1 圆 设计圆类 包含 包含基本属性和基本属性访问接口 计算面积和周长接口 2 1 圆 1 #include 2 using namespace std ; 3 c l a s s CCircle 4 { 5 p r i v a t e : 6 double r ; 7 const

More information

untitled

untitled 3 C++ 3.1 3.2 3.3 3.4 new delete 3.5 this 3.6 3.7 3.1 3.1 class struct union struct union C class C++ C++ 3.1 3.1 #include struct STRING { typedef char *CHARPTR; // CHARPTR s; // int strlen(

More information

FY.DOC

FY.DOC 高 职 高 专 21 世 纪 规 划 教 材 C++ 程 序 设 计 邓 振 杰 主 编 贾 振 华 孟 庆 敏 副 主 编 人 民 邮 电 出 版 社 内 容 提 要 本 书 系 统 地 介 绍 C++ 语 言 的 基 本 概 念 基 本 语 法 和 编 程 方 法, 深 入 浅 出 地 讲 述 C++ 语 言 面 向 对 象 的 重 要 特 征 : 类 和 对 象 抽 象 封 装 继 承 等 主

More information

程序设计与算法语言 静态与友元 C/C++ Programming and Algorithms Static, Friend and Const Dongke Sun ( 孙东科 ) 东南大学机械工程学院 School of Mechanical Engineer

程序设计与算法语言 静态与友元 C/C++ Programming and Algorithms Static, Friend and Const Dongke Sun ( 孙东科 ) 东南大学机械工程学院 School of Mechanical Engineer 程序设计与算法语言 静态与友元 C/C++ Programming and Algorithms Static, Friend and Const Dongke Sun ( 孙东科 ) dksun@seu.edu.cn 东南大学机械工程学院 School of Mechanical Engineering Southeast University Spring semester, 2019 牢记 80/20

More information

untitled

untitled 1 7 7.1 7.2 7.3 7.4 7.5 2 7.1 VFT virtual 7.1 3 1 1. 2. public protected public 3. VFT 4. this const volatile 4 2 5. ( ) ( ) 7.1 6. no-static virtual 7.2 7. inline 7.3 5 3 8. this this 9. ( ) ( ) delete

More information

Microsoft PowerPoint - 3. 函数Functionl.ppt [兼容模式]

Microsoft PowerPoint - 3. 函数Functionl.ppt [兼容模式] 函数 Function 如何重用代码 How to reuse code 3 4 = 3*3*3*3 3 4,6 5 : 拷贝 - 粘帖代码 (Copy-paste code) 3 4,6 5,12 10 : 拷贝 - 粘帖代码 (Copy-paste code) Bad! 使用函数 (with a function) 使用函数 (with a function) 使用函数 (with a function)

More information

extend

extend (object oriented) Encapsulation Inheritance Polymorphism Dynamic Binding (base class) (derived class) 1 class Base { int I; void X(); void Y(); class Derived: public Base { private: int j; void z(); Derived

More information

<4D F736F F F696E74202D20B5DA3032BDB25FC0E0BACDB6D4CFF3312E BBCE6C8DDC4A3CABD5D>

<4D F736F F F696E74202D20B5DA3032BDB25FC0E0BACDB6D4CFF3312E BBCE6C8DDC4A3CABD5D> 程序设计实习 (I): C++ 程序设计 第二讲类和对象 (1) 面向对象的程序设计 面向对象的程序设计方法, 能够较好解决结构化程序设计中出现的问题 面向对象的程序 = 类 + 类 + + 类 设计程序的过程, 就是设计类的过程 2 面向对象的程序设计 面向对象的程序设计方法 : 将某类客观事物共同特点 ( 属性 ) 归纳出来, 形成一个数据结 构 ( 可以用多个变量描述事物的属性 ); 将这类事物所能进行的行为也归纳出来,

More information

Microsoft Word - chap10.doc

Microsoft Word - chap10.doc 78 10. Inheritance in C++ 我 們 已 介 紹 了 物 件 導 向 程 式 的 第 一 個 主 要 特 性, 即 程 式 可 模 組 化 成 為 類 別 ( 物 件 ), 類 別 具 有 資 料 封 裝 的 特 性 接 下 來 我 們 要 介 紹 物 件 導 向 程 式 的 另 一 個 主 要 特 性, 那 就 是 類 別 具 有 繼 承 的 功 能 繼 承 就 是 重 複

More information

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double x) { d

More information

Microsoft PowerPoint - 4. 数组和字符串Arrays and Strings.ppt [兼容模式]

Microsoft PowerPoint - 4. 数组和字符串Arrays and Strings.ppt [兼容模式] Arrays and Strings 存储同类型的多个元素 Store multi elements of the same type 数组 (array) 存储固定数目的同类型元素 如整型数组存储的是一组整数, 字符数组存储的是一组字符 数组的大小称为数组的尺度 (dimension). 定义格式 : type arrayname[dimension]; 如声明 4 个元素的整型数组 :intarr[4];

More information

无类继承.key

无类继承.key 无类继承 JavaScript 面向对象的根基 周爱 民 / aimingoo aiming@gmail.com https://aimingoo.github.io https://github.com/aimingoo rand = new Person("Rand McKinnon",... https://docs.oracle.com/cd/e19957-01/816-6408-10/object.htm#1193255

More information

2013 C 1 # include <stdio.h> 2 int main ( void ) 3 { 4 int cases, a, b, i; 5 scanf ("%d", & cases ); 6 for (i = 0;i < cases ;i ++) 7 { 8 scanf ("%d %d

2013 C 1 # include <stdio.h> 2 int main ( void ) 3 { 4 int cases, a, b, i; 5 scanf (%d, & cases ); 6 for (i = 0;i < cases ;i ++) 7 { 8 scanf (%d %d 2013 18 ( ) 1. C pa.c, pb.c, 2. C++ pa.cpp, pb.cpp, Compilation Error cin scanf Time Limit Exceeded 1: A 5 B 5 C 5 D 5 E 5 F 5 1 2013 C 1 # include 2 int main ( void ) 3 { 4 int cases, a, b,

More information

untitled

untitled (encapsulation) 例 類 說 類 料 來 料 information hiding 念 (inheritance) 來說 類 類 類 類 類 類 行 利 來 (polymorphism) 不 類 數 不 1 2 3 4 類 類 不 類 不 類 5 6 7 // virtual 不見了 #include #include using namespace

More information

幻灯片 1

幻灯片 1 信息科学技术学院 程序设计实习 郭炜微博 http://weibo.com/guoweiofpku http://blog.sina.com.cn/u/3266490431 刘家瑛微博 http://weibo.com/pkuliujiaying 1 信息科学技术学院 程序设计实习 郭炜刘家瑛 继承和派生 ( 教材 P215) 2 继承和派生的概念 继承 : 在定义一个新的类 B 时, 如果该类与某个已有的类

More information

C/C++语言 - C/C++数据

C/C++语言 - C/C++数据 C/C++ C/C++ Table of contents 1. 2. 3. 4. char 5. 1 C = 5 (F 32). 9 F C 2 1 // fal2cel. c: Convert Fah temperature to Cel temperature 2 # include < stdio.h> 3 int main ( void ) 4 { 5 float fah, cel ;

More information

C 1

C 1 C homepage: xpzhangme 2018 5 30 C 1 C min(x, y) double C // min c # include # include double min ( double x, double y); int main ( int argc, char * argv []) { double x, y; if( argc!=

More information

C 1 # include <stdio.h> 2 int main ( void ) { 4 int cases, i; 5 long long a, b; 6 scanf ("%d", & cases ); 7 for (i = 0;i < cases ;i ++) 8 { 9

C 1 # include <stdio.h> 2 int main ( void ) { 4 int cases, i; 5 long long a, b; 6 scanf (%d, & cases ); 7 for (i = 0;i < cases ;i ++) 8 { 9 201 201 21 ( ) 1. C pa.c, pb.c, 2. C++ pa.cpp, pb.cpp Compilation Error long long cin scanf Time Limit Exceeded 1: A 1 B 1 C 5 D RPG 10 E 10 F 1 G II 1 1 201 201 C 1 # include 2 int main ( void

More information

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 复习 Java 包 创建包 : package 语句, 包结构与目录结构一致 使用包 : import restaurant/ - people/ - Cook.class - Waiter.class - tools/ - Fork.class - Table.class

More information

《C语言程序设计》教材习题参考答案

《C语言程序设计》教材习题参考答案 教材名称 : C 语言程序设计 ( 第 1 版 ) 黄保和 江弋编著清华大学出版社 ISBN:978-7-302-13599-9, 红色封面 答案制作时间 :2011 年 2 月 -5 月 一 选择题 1. 设已定义 int a, * p, 下列赋值表达式中正确的是 :C)p=&a 2. 设已定义 int x,*p=&x;, 则下列表达式中错误的是 :B)&*x 3. 若已定义 int a=1,*b=&a;,

More information

Microsoft PowerPoint - 04-Inheritance.ppt

Microsoft PowerPoint - 04-Inheritance.ppt 继承 派生与多态性 1 本章主要内容 类的继承与派生 类成员的访问控制 简单继承与多重继承 派生类的构造 析构函数 多态性 2 1 类的继承与派生 保持已有类的特性, 并在其基础上产生新的类, 称新类继承了已有类的特征, 或称已有类派生出新类 被继承的已有类称为基类 ( 或父类 ) 派生出的新类称为派生类 派生类将自动继承基类的所有特性 ( 属性和方法 ) 派生类可以定义新的特性 ( 属性和方法 )

More information

C/C++ - 文件IO

C/C++ - 文件IO C/C++ IO Table of contents 1. 2. 3. 4. 1 C ASCII ASCII ASCII 2 10000 00100111 00010000 31H, 30H, 30H, 30H, 30H 1, 0, 0, 0, 0 ASCII 3 4 5 UNIX ANSI C 5 FILE FILE 6 stdio.h typedef struct { int level ;

More information

untitled

untitled A, 3+A printf( ABCDEF ) 3+ printf( ABCDEF ) 2.1 C++ main main main) * ( ) ( ) [ ].* ->* ()[] [][] ** *& char (f)(int); ( ) (f) (f) f (int) f int char f char f(int) (f) char (*f)(int); (*f) (int) (

More information

Strings

Strings Polymorphism and Virtual Functions Cheng-Chin Chiang Virtual Function Basics 多 型 (Polymorphism) 賦 予 一 個 函 數 多 種 意 涵, 存 在 於 同 一 類 別 之 內 祖 先 類 別 與 後 代 類 別 間 物 件 導 向 程 式 設 計 基 本 原 理 虛 擬 函 數 (Virtual Function)

More information

<4D6963726F736F667420506F776572506F696E74202D20332D322E432B2BC3E6CFF2B6D4CFF3B3CCD0F2C9E8BCC6A1AAD6D8D4D8A1A2BCCCB3D0A1A2B6E0CCACBACDBEDBBACF2E707074>

<4D6963726F736F667420506F776572506F696E74202D20332D322E432B2BC3E6CFF2B6D4CFF3B3CCD0F2C9E8BCC6A1AAD6D8D4D8A1A2BCCCB3D0A1A2B6E0CCACBACDBEDBBACF2E707074> 程 序 设 计 实 习 INFO130048 3-2.C++ 面 向 对 象 程 序 设 计 重 载 继 承 多 态 和 聚 合 复 旦 大 学 计 算 机 科 学 与 工 程 系 彭 鑫 pengxin@fudan.edu.cn 内 容 摘 要 方 法 重 载 类 的 继 承 对 象 引 用 和 拷 贝 构 造 函 数 虚 函 数 和 多 态 性 类 的 聚 集 复 旦 大 学 计 算 机 科 学

More information

运算符重载 为什么要 运算符重载 那些运算符可以重载, 哪些不可以 如何实现运算符重载 实现方式 : 成员函数与非成员函数 类型转换 怎样实现对象与基本数据类型数据的运算 2

运算符重载 为什么要 运算符重载 那些运算符可以重载, 哪些不可以 如何实现运算符重载 实现方式 : 成员函数与非成员函数 类型转换 怎样实现对象与基本数据类型数据的运算 2 第十一讲 运算符重载 与类型转换 运算符重载 为什么要 运算符重载 那些运算符可以重载, 哪些不可以 如何实现运算符重载 实现方式 : 成员函数与非成员函数 类型转换 怎样实现对象与基本数据类型数据的运算 2 为什么要运算符重载 预定义的运算符只针对基本数据类型, 若要对类的对象进行类似的运算, 需要重新定义运算符的功能 运算符重载实质就是函数重载 : 对已有的运算符赋予多重含义, 使得同一个运算符作用于不同类型的数据时导致不同的行为

More information

幻灯片 1

幻灯片 1 第四课类和对象 ( 构造深入 ) 互联网新技术在线教育领航者 1 内容概述 1. 数据成员指针 2. 成员函数指针 3. 三 / 五法则 4. 引用计数 5. 写时拷贝 6.swap 函数 7. 移动构造函数 8. 移动赋值运算符重载 9. 对象移动 10.std::vector 动态增长 11.std::vector 与移动 12. 移动小结 互联网新技术在线教育领航者 2 数据成员指针 定义 :

More information

untitled

untitled 1 Outline 數 料 數 數 列 亂數 練 數 數 數 來 數 數 來 數 料 利 料 來 數 A-Z a-z _ () 不 數 0-9 數 不 數 SCHOOL School school 數 讀 school_name schoolname 易 不 C# my name 7_eleven B&Q new C# (1) public protected private params override

More information

幻灯片 1

幻灯片 1 第三课类和对象 ( 封装 ) 互联网新技术在线教育领航者 1 内容概述 1. 封装的概念 2. 访问控制 3. 栈类的封装 4. 构造与析构 5.myString 构造函数 6. 构造与析构的次序 7. 类文件写法 8. 对象的内存 9.this 指针初探 10. 构造函数初始值列表 11. 拷贝构造和赋值运算符重载 12. 浅拷贝 13. 深拷贝 14. 成员函数内联 15. 友元 16.const

More information

新版 明解C++入門編

新版 明解C++入門編 511!... 43, 85!=... 42 "... 118 " "... 337 " "... 8, 290 #... 71 #... 413 #define... 128, 236, 413 #endif... 412 #ifndef... 412 #if... 412 #include... 6, 337 #undef... 413 %... 23, 27 %=... 97 &... 243,

More information

Microsoft PowerPoint - 第06讲_继承.ppt [兼容模式]

Microsoft PowerPoint - 第06讲_继承.ppt [兼容模式] 程序设计实习 (I): C++ 程序设计 第六讲继承 上节内容回顾 三种运算符重载的实现方式 重载为普通函数 重载为成员函数 重载为友元 常见的运算符重载 流运算符 (>>

More information

Microsoft Word - 第3章.doc

Microsoft Word - 第3章.doc 第 3 章 类和对象 Ⅱ 常见考点 常对象的使用方法 常数据成员和常成员函数的使用方法 mutable 数据成员的特点 构造函数中初始化列表的使用方法 explicit 关键字的作用 子对象的使用方法 使用类前向引用声明的情况 子对象构造函数的设计和执行次序 静态子对象的特点 嵌套类和局部类的设计方法与作用 3.1 常对象和常对象成员 3.1.1 要点归纳 1. 常对象常对象是指对象常量, 其一般定义格式如下

More information

提纲 1 联编与多态性 2 用虚函数实现多态 3 虚函数的工作原理 4 纯虚函数与抽象类 5 总结与思考 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 36

提纲 1 联编与多态性 2 用虚函数实现多态 3 虚函数的工作原理 4 纯虚函数与抽象类 5 总结与思考 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 36 程序设计与算法语言 虚函数 C/C++ Programming and Algorithms Virtual Function Dongke Sun ( 孙东科 ) dksun@seu.edu.cn 东南大学机械工程学院 School of Mechanical Engineering Southeast University April 12, 2018 提纲 1 联编与多态性 2 用虚函数实现多态

More information

软件工程文档编制

软件工程文档编制 实训抽象类 一 实训目标 掌握抽象类的定义 使用 掌握运行时多态 二 知识点 抽象类的语法格式如下 : public abstract class ClassName abstract void 方法名称 ( 参数 ); // 非抽象方法的实现代码 在使用抽象类时需要注意如下几点 : 1 抽象类不能被实例化, 实例化的工作应该交由它的子类来完成 2 抽象方法必须由子类来进行重写 3 只要包含一个抽象方法的抽象类,

More information

chap07.key

chap07.key #include void two(); void three(); int main() printf("i'm in main.\n"); two(); return 0; void two() printf("i'm in two.\n"); three(); void three() printf("i'm in three.\n"); void, int 标识符逗号分隔,

More information

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 复习 Protected 可以被子类 / 同一包中的类访问, 不能被其他类访问 弱化的 private 同时赋予 package access class MyType { public int i; public double d; public char

More information

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double x) { d =

More information

C++ 程式設計

C++ 程式設計 C C 料, 數, - 列 串 理 列 main 數串列 什 pointer) 數, 數, 數 數 省 不 不, 數 (1) 數, 不 數 * 料 * 數 int *int_ptr; char *ch_ptr; float *float_ptr; double *double_ptr; 數 (2) int i=3; int *ptr; ptr=&i; 1000 1012 ptr 數, 數 1004

More information

《C语言程序设计》第2版教材习题参考答案

《C语言程序设计》第2版教材习题参考答案 教材 C 语言程序设计 ( 第 2 版 ) 清华大学出版社, 黄保和, 江弋编著 2011 年 10 月第二版 ISBN:978-7-302-26972-4 售价 :35 元 答案版本 本习题答案为 2012 年 2 月修订版本 一 选择题 1. 设已定义 int a, * p, 下列赋值表达式中正确的是 :C)p = &a A. *p = *a B. p = *a C.p = &a D. *p =

More information

C++ 程序设计 实验 1 - 参考答案 MASTER 2017 年 5 月 21 日 1

C++ 程序设计 实验 1 - 参考答案 MASTER 2017 年 5 月 21 日 1 C++ 程序设计 实验 1 - 参考答案 MASTER 2017 年 5 月 21 日 1 1 简单图形 1 简单图形 输入图形的行数 ( 如下图 7 行 ), 输出如下图所示图形 * *** ***** ******* ***** *** * 2 1 简单图形 1 #inc lude 2 using namespace std ; 3 4 // 注意变量命名的方式 5 //

More information

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.06.doc

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.06.doc 2 5 8 11 0 13 1. 13 2. 15 3. 18 1 23 1. 23 2. 26 3. 28 2 36 1. 36 2. 39 3. 42 4. 44 5. 49 6. 51 3 57 1. 57 2. 60 3. 64 4. 66 5. 70 6. 75 7. 83 8. 85 9. 88 10. 98 11. 103 12. 108 13. 112 4 115 1. 115 2.

More information

OOP with Java 通知 Project 3 提交时间 3 月 29 日晚 9 点 Piazza Project 2 投票

OOP with Java 通知 Project 3 提交时间 3 月 29 日晚 9 点 Piazza Project 2 投票 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 3 提交时间 3 月 29 日晚 9 点 Piazza Project 2 投票 复习 创建对象 构造函数 函数重载 : 函数 = 函数名 + 参数列表 public class MyType { int i; double d; char c; void set(double x)

More information

Book1

Book1 經 辦 網 點 名 稱 網 點 位 址 第 一 支 行 營 業 室 廣 東 省 廣 州 市 越 秀 區 沿 江 中 路 193 號 第 二 支 行 營 業 室 廣 東 省 廣 州 市 沿 江 西 路 145 號 吉 祥 支 行 廣 東 省 廣 州 市 東 風 中 路 313 號 荔 灣 支 行 營 業 室 廣 東 省 廣 州 市 荔 灣 區 南 岸 路 63 號 三 樓 北 京 路 支 行 營 業

More information

OOP with Java 通知 Project 4: 推迟至 4 月 25 日晚 9 点

OOP with Java 通知 Project 4: 推迟至 4 月 25 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 推迟至 4 月 25 日晚 9 点 复习 Protected 可以被子类 / 同一包中的类访问, 不能被其他类访问 弱化的 private 同时赋予 package access class MyType { public int i; public double d; public

More information

02

02 Thinking in C++: Volume One: Introduction to Standard C++, Second Edition & Volume Two: Practical Programming C++ C C++ C++ 3 3 C C class C++ C++ C++ C++ string vector 2.1 interpreter compiler 2.1.1 BASIC

More information

提问袁小兵:

提问袁小兵: C++ 面 试 试 题 汇 总 柯 贤 富 管 理 软 件 需 求 分 析 篇 1. STL 类 模 板 标 准 库 中 容 器 和 算 法 这 部 分 一 般 称 为 标 准 模 板 库 2. 为 什 么 定 义 虚 的 析 构 函 数? 避 免 内 存 问 题, 当 你 可 能 通 过 基 类 指 针 删 除 派 生 类 对 象 时 必 须 保 证 基 类 析 构 函 数 为 虚 函 数 3.

More information

Microsoft Word - 970617cppFinalSolution.doc

Microsoft Word - 970617cppFinalSolution.doc 國 立 台 灣 海 洋 大 學 資 訊 工 程 系 C++ 程 式 設 計 期 末 考 參 考 答 案 姓 名 : 系 級 : 學 號 : 97/06/17 考 試 時 間 :10:00 12:10 試 題 敘 述 蠻 多 的, 看 清 楚 題 目 問 什 麼, 針 對 重 點 回 答 是 很 重 要 的 ; 不 確 定 的 請 一 定 要 當 場 提 出 來, 不 要 白 花 力 氣 在 誤 會

More information

第六讲 数组、指针与字符串

第六讲 数组、指针与字符串 第六章数组指针与字符串 本章主要内容 数组 指针 动态存储分配 指针与数组 指针与函数 vector 的基本用法 字符串 深度探索 2 数组的概念 数组是具有一定顺序关系的若干相 同类型变量的集合体, 组成数组的变量 称为该数组的元素 数组属于构造类型 数组3 数组名的构成方法与一般变量名相同 数组一维数组的声明与引用 一维数组的声明 类型说明符数组名 [ 常量表达式 ]; 例如 :int a[10];

More information

untitled

untitled 1 DBF (READDBF.C)... 1 2 (filetest.c)...2 3 (mousetes.c)...3 4 (painttes.c)...5 5 (dirtest.c)...9 6 (list.c)...9 1 dbf (readdbf.c) /* dbf */ #include int rf,k,reclen,addr,*p1; long brec,erec,i,j,recnum,*p2;

More information

Microsoft PowerPoint - 5. 指针Pointers.ppt [兼容模式]

Microsoft PowerPoint - 5. 指针Pointers.ppt [兼容模式] 指针 Pointers 变量指针与指针变量 Pointer of a variable 变量与内存 (Variables and Memory) 当你声明一个变量时, 计算机将给该变量一个内存, 可以存储变量的值 当你使用变量时, 计算机将做两步操作 : - 根据变量名查找其对应的地址 ; - 通过地址对该地址的变量内容进行读 (retrieve) 或写 (set) 变量的地址称为变量的指针! C++

More information

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 复习 Protected 可以被子类 / 同一包中的类访问, 不能被其他类访问 弱化的 private 同时赋予 package access class MyType { public int i; public double d; public char

More information

Microsoft PowerPoint - 07 派生数据类型

Microsoft PowerPoint - 07 派生数据类型 能源与动力工程学院 目录 派生类型 陈 斌 固有数据类型 数值型 (numerical) 整型 INTEGER 实型 REAL 复数型 COMPLEX 非数值型 字符型 CHARACTER 逻辑型 ( 布尔型 )LOGICAL 自定义数据类型 ( 派生类型, derived type) 派生类型是指用户利用 Fortran 系统内部类型, 如整型 实型 复数型 逻辑型 字符型等的组合自行创建出一个新的数据类型,

More information

untitled

untitled 1 Outline 類别 欄 (1) 類 類 狀 更 易 類 理 若 類 利 來 利 using 來 namespace 類 ; (2) namespace IBM class Notebook namespace Compaq class Notebook 類别 類 來 類 列 欄 (field) (property) (method) (event) 類 例 立 來 車 類 類 立 車 欄 料

More information

第四章 类与对象

第四章 类与对象 第四章类与对象 信息工程学院王红平 Email:cugwhp@qq.com 本章主要内容 面向对象的思想 OOP 的基本特点 类和对象 构造函数和析构函数 类的组合 结构体和联合体 2 回顾 : 面向过程的设计方法 面向对象的思想 重点 : 如何实现细节过程, 将数据与函数分开 形式 : 主模块 + 若干个子模块 (main()+ 子函数 ) 特点 : 自顶向下, 逐步求精 功能分解 缺点 : 效率低,

More information

北京大学

北京大学 1 string 类 郭炜刘家瑛 北京大学程序设计实习 string 类 string 类是一个模板类, 它的定义如下 : typedef basic_string string; 使用 string 类要包含头文件 string 对象的初始化 : string s1("hello"); // 一个参数的构造函数 string s2(8, x ); // 两个参数的构造函数

More information

Microsoft Word - 第3章.doc

Microsoft Word - 第3章.doc 第 3 章 lambda 表达式及其应用 lambda 表达式是 Java 8 提供的一种新特性, 它使得 Java 也能像 C# 和 C++ 语言一样进行简单的 函数式编程, 这不仅简化了某些通用结构的实现方式, 也大大增强了 Java 语言的表达功能 3.1 lambda 表达式简介 lambda 表达式是基于数学中的 λ 演算得名, 本质上就是一个没有方法名的匿名方法 例如, 有一个方法定义如下

More information

上海交通大学

上海交通大学 一 读程序, 写结果 ( 每题 4 分, 共 40 分 ) 1. 写出下列程序运行结果 class test friend test operator+(const test &p1, const test &p2) return test(p1.data1 + p2.data1, p1.data2 + p2.data2); friend ostream &operator

More information

Modeling & Simulation 数学原理 物理规律和程序设计的综合 Magic Fluids Heart Simulator Dongke Sun (Southeast University) C++ Programming and Algorithms April 23,

Modeling & Simulation 数学原理 物理规律和程序设计的综合 Magic Fluids Heart Simulator Dongke Sun (Southeast University) C++ Programming and Algorithms April 23, 程序设计与算法语言 继承与派生 C/C++ Programming and Algorithms Inheritance and Derivation Dongke Sun ( 孙东科 ) dksun@seu.edu.cn 东南大学机械工程学院 School of Mechanical Engineering Southeast University April 23, 2018 Modeling

More information

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.07.doc

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.07.doc 2 5 8 11 0 1. 13 2. 15 3. 18 1 1. 22 2. 25 3. 27 2 1. 35 2. 38 3. 41 4. 43 5. 48 6. 50 3 1. 56 2. 59 3. 63 4. 65 5. 69 13 22 35 56 6. 74 7. 82 8. 84 9. 87 10. 97 11. 102 12. 107 13. 111 4 114 1. 114 2.

More information

Chapter 9: Objects and Classes

Chapter 9: Objects and Classes Fortran Algol Pascal Modula-2 BCPL C Simula SmallTalk C++ Ada Java C# C Fortran 5.1 message A B 5.2 1 class Vehicle subclass Car object mycar public class Vehicle extends Object{ public int WheelNum

More information

C

C C 2017 3 14 1. 2. 3. 4. 2/95 C 1. 3/95 C I 1 // talkback.c: 2 #include 3 #include 4 #define DENSITY 62.4 5 int main(void) 6 { 7 float weight, volume; 8 int size; 9 unsigned long letters;

More information

试卷代号 :1075 座位号 rn 国家开放大学 ( 中央广播电视大学 )2015 年秋季学期 " 开放本科 " 期末考试 c+ 十语言程序设计试题 2016 年 1 月 t 问一 Urr-f 斗 士 1 1. 下面的保留字 ( ) 不能作为函数的返回类型 A. void B. int C. new

试卷代号 :1075 座位号 rn 国家开放大学 ( 中央广播电视大学 )2015 年秋季学期  开放本科  期末考试 c+ 十语言程序设计试题 2016 年 1 月 t 问一 Urr-f 斗 士 1 1. 下面的保留字 ( ) 不能作为函数的返回类型 A. void B. int C. new 试卷代号 :1075 座位号 rn 国家开放大学 ( 中央广播电视大学 )2015 年秋季学期 " 开放本科 " 期末考试 c+ 十语言程序设计试题 2016 年 1 月 t 问一 Urr-f 斗 士 1 1. 下面的保留字 ( ) 不能作为函数的返回类型 A. void B. int C. new D. long 2. 在每个 C 十 + 程序中都必须包含有这样一个函数, 该函数的函数名为 ) A.main

More information

第五讲 C++程序的结构

第五讲 C++程序的结构 第五章数据的共享与保护 本章主要内容 作用域与可见性 对象的生存期 数据与函数 静态成员 共享数据的保护 友元 编译预处理命令 多文件结构和工程 深度探索 2 命名空间作用域作用域与可见性标识符的作用域 标识符在程序正文中有效的区域 函数原型作用域 局部作用域 类作用域 3 作用域与可见性函数原型的作用域 函数原型中的参数, 其作用域始于 "(", 结束于 ")" 例如, 设有下列原型声明 : double

More information

新・解きながら学ぶJava

新・解きながら学ぶJava 481! 41, 74!= 40, 270 " 4 % 23, 25 %% 121 %c 425 %d 121 %o 121 %x 121 & 199 && 48 ' 81, 425 ( ) 14, 17 ( ) 128 ( ) 183 * 23 */ 3, 390 ++ 79 ++ 80 += 93 + 22 + 23 + 279 + 14 + 124 + 7, 148, 16 -- 79 --

More information

C/C++ - 函数

C/C++ - 函数 C/C++ Table of contents 1. 2. 3. & 4. 5. 1 2 3 # include # define SIZE 50 int main ( void ) { float list [ SIZE ]; readlist (list, SIZE ); sort (list, SIZE ); average (list, SIZE ); bargragh

More information

没有幻灯片标题

没有幻灯片标题 指针作为函数参数 : 原因 : 1 需要修改一个或多个值,( 用 return 语句不能解决问题 ) 2 执行效率的角度 使用方法 : 在函数原型以及函数首部中需要声明能够接受指针值的形参, 具体的写法为 : 数据类型 * 形参名 如果有多个指针型形参, 则用逗号分隔, 例如 : void swap(int *p1, int *p2) 它说明了形参 p1 p2 是指向整型变量的指针 在函数调用时,

More information

程序设计与算法语言 结构体 共同体和枚举类型 C/C++ Programming and Algorithms struct, union and enum types Dongke Sun ( 孙东科 ) 东南大学机械工程学院 School of Mechanic

程序设计与算法语言 结构体 共同体和枚举类型 C/C++ Programming and Algorithms struct, union and enum types Dongke Sun ( 孙东科 ) 东南大学机械工程学院 School of Mechanic 程序设计与算法语言 结构体 共同体和枚举类型 C/C++ Programming and Algorithms struct, union and enum types Dongke Sun ( 孙东科 ) dksun@seu.edu.cn 东南大学机械工程学院 School of Mechanical Engineering Southeast University Spring semester,

More information

1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 ->

1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 -> 目录 1 大概思路... 1 2 创建 WebAPI... 1 3 创建 CrossMainController 并编写... 1 4 Nuget 安装 microsoft.aspnet.webapi.cors... 4 5 跨域设置路由... 4 6 编写 Jquery EasyUI 界面... 5 7 运行效果... 7 8 总结... 7 1 1 大概思路 创建 WebAPI 创建 CrossMainController

More information

第五讲 数组 一维数组 二维数组 数组作为函数参数

第五讲 数组 一维数组 二维数组 数组作为函数参数 第五讲 数组 一维数组 二维数组 数组作为函数参数 一维数组 2 数组 数组 : 具有一定顺序关系的若干相同类型变量的集合体 一维数组的声明 类型标识符变量名 [n] 声明一个长度为 n 的数组 ( 向量 ) 类型标识符 : 数组元素的数据类型 ; n: 数组的长度, 即元素的个数 ; 例 : int x[5] // 声明一个长度为 5 的一维数组 一维数组的引用 变量名 [k] // 注 : 下标

More information

IO

IO 1 C/C++ C FILE* fscanf fgets fread fprintf fputs fwrite C++ ifstream ofstream >>

More information

Microsoft PowerPoint - ch12 [Compatibility Mode]

Microsoft PowerPoint - ch12 [Compatibility Mode] 第十二章 面向对象语言的编译 本章内容 概述面向对象语言的重要概念和实现技术 以 C++ 语言为例, 介绍如何将 C++ 程序翻译成 C 程序 实际的编译器大都把 C++ 程序直接翻译成低级语言程序 12.1 面向对象语言的概念 12.1.1 对象和对象类 对象 由一组属性和操作于这组属性的过程组成 属性到值的映射称为对象的状态, 过程称为方法 对象类 一类对象的总称, 规范了该类中对象的属性和方法,

More information

OOP with Java 通知 Project 2 提交时间 : 3 月 21 日晚 9 点 作业提交格式 学习使用 文本编辑器 cmd, PowerShell (Windows), terminal(linux, Mac)

OOP with Java 通知 Project 2 提交时间 : 3 月 21 日晚 9 点 作业提交格式 学习使用 文本编辑器 cmd, PowerShell (Windows), terminal(linux, Mac) OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 2 提交时间 : 3 月 21 日晚 9 点 作业提交格式 学习使用 文本编辑器 cmd, PowerShell (Windows), terminal(linux, Mac) 复习 面向对象编程 将实际问题分解成不同的对象 不的对象提供不同的服务 对象之间可以传递消息 例子小李深夜

More information

Microsoft Word - 第3章.doc

Microsoft Word - 第3章.doc Java C++ Pascal C# C# if if if for while do while foreach while do while C# 3.1.1 ; 3-1 ischeck Test() While ischeck while static bool ischeck = true; public static void Test() while (ischeck) ; ischeck

More information

1

1 1 2 3 4 5 GNUDebugger 6 7 void main(int argc, char **argv){ vulncpy(argv[1]); return; } void vulncpy(char *a){ char buf[30]; strcpy(buf, a); return; } *argv[1] buf Shellcode *argv[1]... &buf &buf 8 strcpy

More information

Microsoft Word - ch04三校.doc

Microsoft Word - ch04三校.doc 4-1 4-1-1 (Object) (State) (Behavior) ( ) ( ) ( method) ( properties) ( functions) 4-2 4-1-2 (Message) ( ) ( ) ( ) A B A ( ) ( ) ( YourCar) ( changegear) ( lowergear) 4-1-3 (Class) (Blueprint) 4-3 changegear

More information

面向对象的程序设计 : 抽象 继承和多态 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

面向对象的程序设计 : 抽象 继承和多态 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38 程序设计与算法语言 继承与派生 C/C++ Programming and Algorithms Inheritance and Derivation Dongke Sun ( 孙东科 ) dksun@seu.edu.cn 东南大学机械工程学院 School of Mechanical Engineering Southeast University April 12, 2018 面向对象的程序设计

More information

C++_Lecture

C++_Lecture C++ 程序设计 张岳新编著 苏州大学出版社 1 第十一章 继承和派生类 2 继承性是面向对象程序设计中最重要的机制 这种机制提供了无限重复利用程序资源的一种途径 通过 C++ 语言中的继承机制, 可以扩充和完善旧的程序设计以适应新的需求 这样不仅可以节省程序开发的时间和资源, 并且为未来程序增添了新的资源 3 class Student { int num; char name[30]; char

More information

KillTest 质量更高 服务更好 学习资料 半年免费更新服务

KillTest 质量更高 服务更好 学习资料   半年免费更新服务 KillTest 质量更高 服务更好 学习资料 http://www.killtest.cn 半年免费更新服务 Exam : 310-065Big5 Title : Sun Certified Programmer for the Java 2 Platform, SE 6.0 Version : Demo 1 / 14 1. 35. String #name = "Jane Doe"; 36. int

More information

第四章 类与对象

第四章 类与对象 第四章类与对象 中国科大 黄章进 本章主要内容 面向对象的思想 OOP 的基本特点 类概念和声明 对象 构造函数 析构函数 内联成员函数 拷贝构造函数 类的组合 结构体与联合体 深度探索 2 效率低, 程序的可重用性差 面向对象的思想回顾 : 面向过程的设计方法 重点 : 如何实现的细节和过程, 将数据与函数分开 形式 : 主模块 + 若干个子模块 (main()+ 子函数 ) 特点 : 自顶向下,

More information