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

Size: px
Start display at page:

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

Transcription

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

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

3 提纲 1 访问冲突 2 支配规则 3 虚基类与构造函数 4 赋值兼容及其限制 5 总结与思考 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

4 提纲 访问冲突 1 访问冲突 2 支配规则 3 虚基类与构造函数 4 赋值兼容及其限制 5 总结与思考 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

5 访问冲突 访问冲突 在类的多重继承情况下, 1 派生类对其自身及基类成员的访问应该是唯一的和无争议的 ; 2 然而, 派生类有时会面临对基类成员的访问出现冲突的情况 这种发生访问冲突的现象就是多继承中的访问冲突, 也可称之为二义性问题 发生二义性的两种情况 : 名称冲突 : 派生类在访问基类成员 ( 成员函数和成员变量 ) 时, 由于基类存在同名的成员, 导致无法确定访问的是哪个基类的成员, 因此出现了二义性错误 歧义基类 : 当一个派生类从多个基类派生时, 而这些基类又有一个共同的基类, 当对这个共同的基类中说明的成员进行访问时, 可能出现二义性问题 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

6 访问冲突 访问冲突 派生类在访问基类成员函数时, 由于基类存在同名的成员函数, 导致无法确定访问的是哪个基类的成员函数, 因此出现了二义性错误 例程 : 1 class Base1 2 { 3 public: 4 void fun() { cout<<"base1 "<<endl; } 5 }; 6 class Base2 7 { 8 public: 9 void fun() { cout<<"base2 "<<endl; } 10 }; 11 class Derived : public Base1, public Base2 12 { 13 }; 14 int main() 15 { 16 Derived obj; 17 obj.fun(); // 产生歧义无法确定访问的是继承自 Base1 的还是 Base2 的 18 return 0; 19 } Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

7 访问冲突 访问冲突 派生类在访问基类成员变量时, 由于基类存在同名的成员变量, 导致无法确定访问的是哪个基类的成员变量, 因此出现了二义性错误 例程 : 1 class BaseA 2 { 3 protected: 4 int data; // 出现一次 5 public: 6 BaseA(int d) { data=d; } 7 function(int num) {...}; 8 }; 1 class BaseB 2 { 3 protected: 4 int data; // 出现一次 5 public: 6 BaseB(int d) { data=d; } 7 function(int num) {...}; 8 }; 1 class Derived : public BaseA, public BaseB // 公有继承基类 2 { 3 public: 4 Derived(int a, int b) : BaseA(a), BaseB(b) 5 { data=function(a)+function(b); } // 访问 function 出现了二义性 6 void SetData(int d_loc) { data=d_loc; } // 访问 data 出现了二义性 7 } 名称冲突 : 当不同基类中出现同名的成员函数或成员变量时, 在派生类中访问这种成员函数或成员变量就会出现名称访问的二义性 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

8 访问冲突 访问冲突 Question 派生类在访问基类成员变量时, 由于基类存在同名的成员变量, 导致无法确请问定访问的是哪个基类的成员变量 : 一个 Derived 的对象有多少个成员变量和成员函数, 因此出现了二义性错误 例程? : 1 class BaseA 2 { 3 protected: 4 int data; // 出现一次 5 public: 6 BaseA(int d) { data=d; } 7 function(int num) {...}; 8 }; 1 class BaseB 2 { 3 protected: 4 int data; // 出现一次 5 public: 6 BaseB(int d) { data=d; } 7 function(int num) {...}; 8 }; 1 class Derived : public BaseA, public BaseB // 公有继承基类 2 { 3 public: 4 Derived(int a, int b) : BaseA(a), BaseB(b) 5 { data=function(a)+function(b); } // 访问 function 出现了二义性 6 void SetData(int d_loc) { data=d_loc; } // 访问 data 出现了二义性 7 } 名称冲突 : 当不同基类中出现同名的成员函数或成员变量时, 在派生类中访问这种成员函数或成员变量就会出现名称访问的二义性 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

9 访问冲突 访问冲突 当一个派生类从多个基类派生时, 而这些基类又有一个共同的基类, 当对这个共同的基类中说明的成员进行访问时, 可能出现二义性问题 1 class Base 2 { 3 public: 4 int data; 5 }; 6 class DerivedA : public Base 7 { }; 8 class DerivedB : public Base 9 { }; 10 class DerivedD : public DerivedA, public DerivedB 11 { }; int main() 14 { 15 DerivedD obj; 16 obj.data = 1; // 产生二义性 17 return 0; 18 } Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

10 访问冲突 访问冲突 当一个派生类从多个基类派生时, 而这些基类又有一个共同的基类, 当对这个共同的基类中说明的成员进行访问时, 可能出现二义性问题 1 class Base 2 { 3 public: 4 int data; 5 }; 6 class DerivedA : public Base 7 { }; 8 class DerivedB : public Base 9 { }; 10 class DerivedD : public DerivedA, public DerivedB 11 { }; int main() 14 { 15 DerivedD obj; 16 obj.data = 1; // 产生二义性 17 return 0; 18 } 请问 : 一个 DerivedD 的对象有多少个成员变量?sizeof(obj) 是多少? Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

11 访问冲突的解决办法 访问冲突 访问冲突 ( 二义性 ) 的解决办法 在定义基类时, 保证一个基类中的成员名与另一个基类中的成员名绝不相同 ( 极难做到 根本做不到 ) 在派生类中使用作用域运算符限定所访问的成员是属于哪一个基类的, 其格式为 < 基类名称 :: 成员名称 > 1 class Derived : public BaseA, public BaseB // 公有继承基类 2 { 3 public: 4 Derived(int a, int b) : BaseA(a), BaseB(b) 5 { 6 data = BaseA::function(a) // 解决了二义性问题 7 + BaseB::function(b); // 解决了二义性问题 8 } 9 void SetData(int d_loc) 10 { 11 BaseA::data=d_loc; // 解决了二义性问题 12 BaseB::data=d_loc; // 解决了二义性问题 13 } 14 } Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

12 访问冲突的解决办法 访问冲突 当把派生类作为基类, 又派生出新的派生类时, 这种限定作用域的运算符不能连续嵌套使用, 如下形式的使用方式是不允许的 : < 类名 1> :: < 类名 2> :: < 类名 n> :: < 类名 N> :: < 成员名 > 由于 C++ 是通过作用域运算符来解决访问二义性问题, 因此规定任一基类在派生类中只能被直接继承一次, 否则会造成成员名访问的冲突 例如 : 1 class A 2 { 3 public: 4 float data; }; 7 class B: public A, public A // 错误的 8 { }; B 类的定义是错误的 假如允许基类被直接继承一次以上, 那么通过作用域运算符就无法解决访问二义性 ( 访问冲突 ) 问题 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

13 提纲 支配规则 1 访问冲突 2 支配规则 3 虚基类与构造函数 4 赋值兼容及其限制 5 总结与思考 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

14 支配规则 支配规则 支配规则 : 当通过派生类的对象访问基类和派生类中的同名成员时, 派生类的成员被优先访问 ( 可理解为 就近 访问 ) 1 class A 2 { 3 protected: int x; 4 public: 5 void Set(int a) 6 { x=a; } 7 void Show( ) 8 { 9 cout <<"x=" <<x <<endl; 10 } 11 }; 12 class B : public A 13 { 14 protected: 15 int x; 16 public: 17 void SetAx(int a) 程序输出结果 : x=1 x=2 18 { A::x=a; }// 基类 A 的 19 void SetBx(int a) 20 { x = a; }// 派生类 B 的 21 void Show( ) 22 { 23 cout<<"x=" <<x <<endl; 24 } 25 }; 26 int main(void) 27 { 28 B b; 29 b.setax(1); 30 b.setbx(2); 31 b.a::show( ); // 基类 A 的 32 b.show( ); // 派生类 B 的 33 return 0; 34 } Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

15 支配规则 支配规则 支配规则 : 当通过派生类的对象访问基类和派生类中的同名成员时, 派生类的成员被优先访问 ( 可理解为 就近 访问 ) 1 class A 2 { 3 protected: int x; 4 public: 5 void Set(int a) 6 { x=a; } 7 void Show( ) 8 { 9 cout <<"x=" <<x <<endl; 10 } 11 }; 12 class B : public A 13 { 14 protected: 15 int x; 16 public: 17 void SetAx(int a) 程序输出结果 : x=1 x=2 18 { A::x=a; }// 基类 A 的 19 void SetBx(int a) 20 { x = a; }// 派生类 B 的 21 void Show( ) 22 { 23 cout<<"x=" <<x <<endl; 24 } 25 }; 26 int main(void) 27 { 28 B b; 29 b.setax(1); 30 b.setbx(2); 31 b.a::show( ); // 基类 A 的 32 b.show( ); // 派生类 B 的 33 return 0; 34 } 请问 : 类 B 的一个对象有多少个数据成员? Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

16 支配规则 支配规则 同名隐藏 : 派生类中具有和基类同名的函数 ( 不管参数 ) 时, 派生类的该方法将会隐藏掉所有的基类的同名方法 1 class Base 2 { 3 public: 4 Base() {} 5 ~Base() {} 6 public: 7 void show() 8 {cout<<"base::show()\n"; } 9 void show(int x) 10 {cout<<"base::show(int)\n";} 11 }; 12 class D : public Base 13 { 14 public: 15 D() {} 16 ~D() {} 删除出错行, 18 public: 19 void show() 20 { cout <<"D::show()\n"; } 21 }; int main() 24 { 25 D d; 26 d.show( ); // 此处调用的 是 D 类中的 show() 方法 27 d.show(2); // 28 return 0; 29 } Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

17 支配规则 支配规则 同名隐藏 : 派生类中具有和基类同名的函数 ( 不管参数 ) 时, 派生类的该方法将会隐藏掉所有的基类的同名方法 1 class Base 2 { 3 public: 4 Base() {} 5 ~Base() {} 6 public: 7 void show() 8 {cout<<"base::show()\n"; } 9 void show(int x) 10 {cout<<"base::show(int)\n";} 11 }; 12 class D : public Base 13 { 14 public: 15 D() {} 16 ~D() {} 删除出错行, 18 public: 19 void show() 20 { cout <<"D::show()\n"; } 21 }; int main() 24 { 25 D d; 26 d.show( ); // 此处调用的 是 D 类中的 show() 方法 27 d.show(2); // 出错, 因为派生 类中的 show() 隐藏了基类中所有 同名方法, 而派生类中没有带参数 的 show() 方法 28 return 0; 29 } Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

18 支配规则 支配规则 同名隐藏 : 派生类中具有和基类同名的函数 ( 不管参数 ) 时, 派生类的该方法将会隐藏掉所有的基类的同名方法 1 class Base 2 { 3 public: 4 Base() {} 5 ~Base() {} 6 public: 7 void show() 8 {cout<<"base::show()\n"; } 9 void show(int x) 10 {cout<<"base::show(int)\n";} 11 }; 12 class D : public Base 13 { 14 public: 15 D() {} 16 ~D() {} 删除出错行, 则程序输出结果为 :D::show() 18 public: 19 void show() 20 { cout <<"D::show()\n"; } 21 }; int main() 24 { 25 D d; 26 d.show( ); // 此处调用的 是 D 类中的 show() 方法 27 d.show(2); // 出错, 因为派生 类中的 show() 隐藏了基类中所有 同名方法, 而派生类中没有带参数 的 show() 方法 28 return 0; 29 } Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

19 支配规则 支配规则 同名隐藏 : 派生类中具有和基类同名的函数 ( 不管参数 ) 时, 派生类的该方法将会隐藏掉所有的基类的同名方法 1 class Base 2 { 3 public: 4 Base() {} 5 ~Base() {} 6 public: 7 void show() 8 {cout<<"base::show()\n"; } 9 void show(int x) 10 {cout<<"base::show(int)\n";} 11 }; 12 class D : public Base 13 { 14 public: 15 D() {} 16 ~D() {} 18 public: 19 void show() 20 { cout <<"D::show()\n"; } 21 }; int main() 24 { 25 D d; 26 d.show( ); // 此处调用的 是 D 类中的 show() 方法 27 d.show(2); // 出错, 因为派生 类中的 show() 隐藏了基类中所有 同名方法, 而派生类中没有带参数 的 show() 方法 28 return 0; 29 } 删除出错行, 则程序输出结果为 :D::show() 若未特别指明, 则通过派生类对象使用的都是派生类中的同名成员 ; Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

20 支配规则 支配规则 同名隐藏 : 派生类中具有和基类同名的函数 ( 不管参数 ) 时, 派生类的该方法将会隐藏掉所有的基类的同名方法 1 class Base 2 { 3 public: 4 Base() {} 5 ~Base() {} 6 public: 7 void show() 8 {cout<<"base::show()\n"; } 9 void show(int x) 10 {cout<<"base::show(int)\n";} 11 }; 12 class D : public Base 13 { 14 public: 15 D() {} 16 ~D() {} 18 public: 19 void show() 20 { cout <<"D::show()\n"; } 21 }; int main() 24 { 25 D d; 26 d.show( ); // 此处调用的 是 D 类中的 show() 方法 27 d.base::show(2);// 28 return 0; 29 } 删除出错行, 则程序输出结果为 :D::show() 若未特别指明, 则通过派生类对象使用的都是派生类中的同名成员 ; 如要通过派生类对象访问基类中被屏蔽的同名成员, 应使用基类名限定访问被隐藏方法 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

21 支配规则 支配规则 同名隐藏 : 派生类中具有和基类同名的函数 ( 不管参数 ) 时, 派生类的该方法将会隐藏掉所有的基类的同名方法 1 class Base 2 { 3 public: 4 Base() {} 5 ~Base() {} 6 public: 7 void show() 8 {cout<<"base::show()\n"; } 9 void show(int x) 10 {cout<<"base::show(int)\n";} 11 }; 12 class D : public Base 13 { 14 public: 15 D() {} 16 ~D() {} 18 public: 19 void show() 20 { cout <<"D::show()\n"; } 21 }; int main() 24 { 25 D d; 26 d.show( ); // 此处调用的 是 D 类中的 show() 方法 27 d.base::show(2);// 正确, 因为 派生类中的 show() 隐藏了基类中 所有同名方法, 应使用基类名限定 访问被隐藏方法 28 return 0; 29 } 删除出错行, 则程序输出结果为 :D::show() 若未特别指明, 则通过派生类对象使用的都是派生类中的同名成员 ; 如要通过派生类对象访问基类中被屏蔽的同名成员, 应使用基类名限定访问被隐藏方法 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

22 支配规则 支配规则 同名隐藏 : 派生类中具有和基类同名的函数 ( 不管参数 ) 时, 派生类的该方法将会隐藏掉所有的基类的同名方法 1 class Base 2 { 3 public: 4 Base() {} 5 ~Base() {} 6 public: 7 void show() 8 {cout<<"base::show()\n"; } 9 void show(int x) 10 {cout<<"base::show(int)\n";} 11 }; 12 class D : public Base 13 { 14 public: 15 D() {} 16 ~D() {} 18 public: 19 void show() 20 { cout <<"D::show()\n"; } 21 }; int main() 24 { 25 D d; 26 d.show( ); // 此处调用的 是 D 类中的 show() 方法 27 d.base::show(2);// 正确, 因为 派生类中的 show() 隐藏了基类中 所有同名方法, 应使用基类名限定 访问被隐藏方法 28 return 0; 29 } 删除出错行程序输出结果, 则程序输出结果为? :D::show() 若未特别指明, 则通过派生类对象使用的都是派生类中的同名成员 ; 如要通过派生类对象访问基类中被屏蔽的同名成员, 应使用基类名限定访问被隐藏方法 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

23 支配规则 支配规则 同名隐藏 : 派生类中具有和基类同名的函数 ( 不管参数 ) 时, 派生类的该方法将会隐藏掉所有的基类的同名方法 1 class Base 2 { 3 public: 4 Base() {} 5 ~Base() {} 6 public: 7 void show() 8 {cout<<"base::show()\n"; } 9 void show(int x) 10 {cout<<"base::show(int)\n";} 11 }; 12 class D : public Base 13 { 14 public: 15 D() {} 16 ~D() {} 18 public: 19 void show() 20 { cout <<"D::show()\n"; } 21 }; int main() 24 { 25 D d; 26 d.show( ); // 此处调用的 是 D 类中的 show() 方法 27 d.base::show(2);// 正确, 因为 派生类中的 show() 隐藏了基类中 所有同名方法, 应使用基类名限定 访问被隐藏方法 28 return 0; 29 } 删除出错行程序输出结果, 则程序输出结果为? D::show() :D::show() 若未特别指明, 则通过派生类对象使用的都是派生类中的同名成员 Base::show(int) ; 如要通过派生类对象访问基类中被屏蔽的同名成员, 应使用基类名限定访问被隐藏方法 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

24 提纲 虚基类与构造函数 1 访问冲突 2 支配规则 3 虚基类与构造函数 4 赋值兼容及其限制 5 总结与思考 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

25 虚基类与构造函数虚 (virtual) 基类 在下面公有继承关系中, 在类 D 中包含了基类 A 的两个拷贝 ( 副本 ) 在类 D 的成员函数中, 欲访问 A 的成员 x, 则必须以 B::x 和 C::x 区分 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

26 虚基类与构造函数虚 (virtual) 基类 在下面公有继承关系中, 在类 D 中包含了基类 A 的两个拷贝 ( 副本 ) 在类 D 的成员函数中, 欲访问 A 的成员 x, 则必须以 B::x 和 C::x 区分 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

27 虚基类与构造函数虚 (virtual) 基类 在下面公有继承关系中, 在类 D 中包含了基类 A 的两个拷贝 ( 副本 ) 在类 D 的成员函数中, 欲访问 A 的成员 x, 则必须以 B::x 和 C::x 区分 Figure: Non-virtual vs Virtual derivation chains 若欲使公共的基类 A 在派生类中只有一个拷贝 ( 副本 ), 可将 A 说明成虚 (virtual) 基类 继承时, 在基类的类名前加上关键词 :virtual Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

28 虚基类与构造函数虚 (virtual) 基类和赋值兼容 1 class A 2 { 3 protected: 4 int x; 5 public: 6 A (int a=0) { x=a; } 7 }; 8 class B : virtual public A 9 { 10 protected: 11 int y; 12 public: 13 B(int a=0, int b=0) : A(a) 14 { y=b; } 15 }; 16 class C : public virtual A 17 { 18 protected: 19 int z; 20 public: 21 C(int a=0, int c=0) : A(a) 22 { z=c; } 23 }; 24 class D : public B, public C 25 { 26 protected: 27 int k; 28 public: 29 D(int a1=0, int a2=0, int b =0, int c=0, int d=0) : B(a1, b), C(a2, c), k(d) 30 { } 31 void Show( ) 32 { 33 cout << "x=" << x << ", "; 34 cout << "y=" << y << ", "; 35 cout << "z=" << z << ", "; 36 cout << "k=" << k << endl; 37 } 38 }; Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

29 虚基类与构造函数虚 (virtual) 基类和赋值兼容 1 class A 2 { 3 protected: 4 int x; 5 public: 6 A (int a=0) { x=a; } 7 }; 8 class B : virtual public A 9 { 10 protected: 11 int y; 12 public: 13 B(int a=0, int b=0) : A(a) 14 { y=b; } 15 }; 16 class C : public virtual A 17 { 18 protected: 19 int z; 20 public: 21 C(int a=0, int c=0) : A(a) 22 { z=c; } 23 }; 24 class D : public B, public C 25 { 26 protected: 27 int k; 28 public: 29 D(int a1=0, int a2=0, int b =0, int c=0, int d=0) : B(a1, b), C(a2, c), k(d) 30 { } 31 void Show( ) 32 { 33 cout << "x=" << x << ", "; 34 cout << "y=" << y << ", "; 35 cout << "z=" << z << ", "; 36 cout << "k=" << k << endl; 37 } 38 }; 请写出代码段 D obj(1, 1, 2, 3, 4); obj.show( ); 的运行结果 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

30 虚基类与构造函数虚 (virtual) 基类和赋值兼容 提示 : 编译器会隐式地调用基类 A 的默认构造函数 类 D 有多少个对象成员? 1 class A 21 C(int a=0, int c=0) : A(a) 2 { 22 { z=c; } 3 protected: 23 }; 4 int x; 24 class D : public B, public C 5 public: 25 { 6 A (int a=0) { x=a; } 26 protected: 7 }; 27 int k; 8 class B : virtual public A 28 public: 9 { 29 D(int a1=0, int a2=0, int b 10 protected: =0, int c=0, int d=0) : B(a1 11 int y;, b), C(a2, c), k(d) 12 public: 30 { } 13 B(int a=0, int b=0) : A(a) 31 void Show( ) 14 { y=b; } 32 { 15 }; 33 cout << "x=" << x << ", "; 16 class C : public virtual A 34 cout << "y=" << y << ", "; 17 { 35 cout << "z=" << z << ", "; 18 protected: 36 cout << "k=" << k << endl; 19 int z; 37 } 20 public: 38 }; 请写出代码段 D obj(1, 1, 2, 3, 4); obj.show( ); 的运行结果 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

31 虚基类与构造函数虚 (virtual) 基类和赋值兼容 39 int main(void) 40 { 41 D obj(1, 1, 2, 3, 4); obj.show( ); 42 int n(0); A obja; B objb; C objc; 43 cout << "size of n is: " << sizeof(n)<<endl; 44 cout << "size of obj A is: " << sizeof(obja)<<endl; 45 cout << "size of obj B is: " << sizeof(objb)<<endl; 46 cout << "size of obj C is: " << sizeof(objc)<<endl; 47 cout << "size of obj D is: " << sizeof(obj) <<endl; 48 return 0; 49 } 程序的运行结果是 : x=0, y=2, z=3, k=4 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

32 虚基类与构造函数虚 (virtual) 基类和赋值兼容 39 int main(void) 40 { 41 D obj(1, 1, 2, 3, 4); obj.show( ); 42 int n(0); A obja; B objb; C objc; 43 cout << "size of n is: " << sizeof(n)<<endl; 44 cout << "size of obj A is: " << sizeof(obja)<<endl; 45 cout << "size of obj B is: " << sizeof(objb)<<endl; 46 cout << "size of obj C is: " << sizeof(objc)<<endl; 47 cout << "size of obj D is: " << sizeof(obj) <<endl; 48 return 0; 49 } 程序的运行结果是 : x=0, y=2, z=3, k=4 size of n is: 4 size of obj A is: 16 size of obj B is: 16 size of obj C is: 16 size of obj D is: 40 构造函数的调用顺序 : Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

33 虚基类与构造函数虚 (virtual) 基类和赋值兼容 39 int main(void) 40 { 41 D obj(1, 1, 2, 3, 4); obj.show( ); 42 int n(0); A obja; B objb; C objc; 43 cout << "size of n is: " << sizeof(n)<<endl; 44 cout << "size of obj A is: " << sizeof(obja)<<endl; 45 cout << "size of obj B is: " << sizeof(objb)<<endl; 46 cout << "size of obj C is: " << sizeof(objc)<<endl; 47 cout << "size of obj D is: " << sizeof(obj) <<endl; 48 return 0; 49 } 程序的运行结果是 : x=0, y=2, z=3, k=4 size of n is: 4 size of obj A is: 16 size of obj B is: 16 size of obj C is: 16 size of obj D is: 40 构造函数的调用顺序 : 先调用虚基类的构造函数, 再调用非虚基类的构造函数 ; 构造函数调用时, 系统按照继承关系 ( 定义时 ) 的顺序调用 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

34 虚基类与构造函数虚 (virtual) 基类和赋值兼容 如将 29 行改为 29 D(int a1=0, int a2=0, int b=0, int c=0, int d=0) : A(a1), B(a1, b), C(a2, c), k(d) 30 { } 回顾第 44 行 41 D obj(1, 1, 2, 3, 4); obj.show( ); 则程序的运行结果变为 : x=1, y=2, z=3, k=4 size of n is: 4 size of obj A is: 16 size of obj B is: 16 size of obj C is: 16 size of obj D is: 40 构造函数的调用顺序仍然是 : 先调用虚基类的构造函数, 再调用非虚基类的构造函数, 并按照继承关系 ( 定义时 ) 的顺序调用 关于 virtual public 后类的对象之大小, 感兴趣的同学请参考 深入探索 C++ 对象模型 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

35 虚基类与构造函数虚 (virtual) 基类和赋值兼容 在多重继承中, 派生类的构造函数负责该派生类所有基类构造函数以及对象成员 ( 如果有的话 ) 构造函数的调用 派生类构造函数执行顺序如下 : 先调用基类构造函数, 再调用派生类构造函数 ; 先初始化所包含的对象成员, 后初始化普通类型数据成员, 最后执行派生类本身的构造函数 多个基类构造函数的执行顺序取决于定义派生类时的顺序, 与派生类在构造函数中成员初始化列表中的顺序无关 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

36 虚基类与构造函数虚 (virtual) 基类和赋值兼容 在多重继承中, 派生类的构造函数负责该派生类所有基类构造函数以及对象成员 ( 如果有的话 ) 构造函数的调用 派生类构造函数执行顺序如下 : 先调用基类构造函数, 再调用派生类构造函数 ; 先初始化所包含的对象成员, 后初始化普通类型数据成员, 最后执行派生类本身的构造函数 多个基类构造函数的执行顺序取决于定义派生类时的顺序, 与派生类在构造函数中成员初始化列表中的顺序无关 在多重继承中, 派生类有多个基类, 如果有些是虚基类有些是非虚基类, 那么构造函数的调用顺序是 : 无论虚基类与产生对象的派生类相隔多远, 先调用虚基类的构造函数, 再按继承次序调用直接基类的构造函数 ; 当同一层有多个虚基类, 按照继承关系定义的顺序调用它们的构造函数 ; 如果包含类的对象成员, 则按声明次序调用对象成员所属类的构造函数, 然后初始化普通类型数据成员, 最后执行派生类本身的构造函数 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

37 虚基类与构造函数虚 (virtual) 基类和赋值兼容 在多重继承中, 派生类的构造函数负责该派生类所有基类构造函数以及对象成员 ( 如果有的话 ) 构造函数的调用 派生类构造函数执行顺序如下 : 先调用基类构造函数, 再调用派生类构造函数 ; 先初始化所包含的对象成员, 后初始化普通类型数据成员, 最后执行派生类本身的构造函数 多个基类构造函数的执行顺序取决于定义派生类时的顺序, 与派生类在构造函数中成员初始化列表中的顺序无关 在多重继承中, 派生类有多个基类, 如果有些是虚基类有些是非虚基类, 那么构造函数的调用顺序是 : 无论虚基类与产生对象的派生类相隔多远, 先调用虚基类的构造函数, 再按继承次序调用直接基类的构造函数 ; 当同一层有多个虚基类, 按照继承关系定义的顺序调用它们的构造函数 ; 如果包含类的对象成员, 则按声明次序调用对象成员所属类的构造函数, 然后初始化普通类型数据成员, 最后执行派生类本身的构造函数 1 class X : public Y, virtual public Z { } object; 当产生类 X 的对象 object 时, 将产生如下调用顺序 : Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

38 虚基类与构造函数虚 (virtual) 基类和赋值兼容 在多重继承中, 派生类的构造函数负责该派生类所有基类构造函数以及对象成员 ( 如果有的话 ) 构造函数的调用 派生类构造函数执行顺序如下 : 先调用基类构造函数, 再调用派生类构造函数 ; 先初始化所包含的对象成员, 后初始化普通类型数据成员, 最后执行派生类本身的构造函数 多个基类构造函数的执行顺序取决于定义派生类时的顺序, 与派生类在构造函数中成员初始化列表中的顺序无关 在多重继承中, 派生类有多个基类, 如果有些是虚基类有些是非虚基类, 那么构造函数的调用顺序是 : 无论虚基类与产生对象的派生类相隔多远, 先调用虚基类的构造函数, 再按继承次序调用直接基类的构造函数 ; 当同一层有多个虚基类, 按照继承关系定义的顺序调用它们的构造函数 ; 如果包含类的对象成员, 则按声明次序调用对象成员所属类的构造函数, 然后初始化普通类型数据成员, 最后执行派生类本身的构造函数 1 class X : public Y, virtual public Z { } object; 当产生类 X 的对象 object 时, 将产生如下调用顺序 :Z() >Y() >X() Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

39 虚基类与构造函数虚 (virtual) 基类和赋值兼容 最远基类成员原则 : 无论虚基类与产生对象的派生类相隔多远, 先调用虚基类的构造函数, 再按继承次序调用直接基类的构造函数 1 class B0 2 { 3 public: 4 int nv0; 5 void fun() 6 { cout<<"member of B0\n"; } 7 }; 8 class B1: virtual public B0 9 { 10 public: 11 int nv1; 12 }; 13 class B2: virtual public B0 14 { 15 public: 16 int nv2; 17 }; 当产生对象 D1 时, 构造函数调用次序 : 18 class D1: public B1, public B2 19 { 20 public: 21 int nvd; 22 void fun() // 隐藏基类同名函数 23 { cout<<"member of D1\n"; } 24 }; 25 int main() 26 { 27 D1 d1; 28 d1.nv0=2; // 使用最远基类成员 29 d1.fun(); 30 return 0; 31 } 运行结果 : Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

40 虚基类与构造函数虚 (virtual) 基类和赋值兼容 最远基类成员原则 : 无论虚基类与产生对象的派生类相隔多远, 先调用虚基类的构造函数, 再按继承次序调用直接基类的构造函数 1 class B0 2 { 3 public: 4 int nv0; 5 void fun() 6 { cout<<"member of B0\n"; } 7 }; 8 class B1: virtual public B0 9 { 10 public: 11 int nv1; 12 }; 13 class B2: virtual public B0 14 { 15 public: 16 int nv2; 17 }; 当产生对象 D1 时, 构造函数调用次序 : 18 class D1: public B1, public B2 19 { 20 public: 21 int nvd; 22 void fun() // 隐藏基类同名函数 23 { cout<<"member of D1\n"; } 24 }; 25 int main() 26 { 27 D1 d1; 28 d1.nv0=2; // 使用最远基类成员 29 d1.fun(); 30 return 0; 31 } 运行结果 : Member of D1 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

41 虚基类与构造函数虚 (virtual) 基类和赋值兼容 最远基类成员原则 : 无论虚基类与产生对象的派生类相隔多远, 先调用虚基类的构造函数, 再按继承次序调用直接基类的构造函数 1 class B0 2 { 3 public: 4 int nv0; 5 void fun() 6 { cout<<"member of B0\n"; } 7 }; 8 class B1: virtual public B0 9 { 10 public: 11 int nv1; 12 }; 13 class B2: virtual public B0 14 { 15 public: 16 int nv2; 17 }; 当产生对象 D1 时, 构造函数调用次序 :B0() 18 class D1: public B1, public B2 19 { 20 public: 21 int nvd; 22 void fun() // 隐藏基类同名函数 23 { cout<<"member of D1\n"; } 24 }; 25 int main() 26 { 27 D1 d1; 28 d1.nv0=2; // 使用最远基类成员 29 d1.fun(); 30 return 0; 31 } 运行结果 : Member of D1 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

42 虚基类与构造函数虚 (virtual) 基类和赋值兼容 最远基类成员原则 : 无论虚基类与产生对象的派生类相隔多远, 先调用虚基类的构造函数, 再按继承次序调用直接基类的构造函数 1 class B0 2 { 3 public: 4 int nv0; 5 void fun() 6 { cout<<"member of B0\n"; } 7 }; 8 class B1: virtual public B0 9 { 10 public: 11 int nv1; 12 }; 13 class B2: virtual public B0 14 { 15 public: 16 int nv2; 17 }; 当产生对象 D1 时, 构造函数调用次序 :B0() B1() 18 class D1: public B1, public B2 19 { 20 public: 21 int nvd; 22 void fun() // 隐藏基类同名函数 23 { cout<<"member of D1\n"; } 24 }; 25 int main() 26 { 27 D1 d1; 28 d1.nv0=2; // 使用最远基类成员 29 d1.fun(); 30 return 0; 31 } 运行结果 : Member of D1 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

43 虚基类与构造函数虚 (virtual) 基类和赋值兼容 最远基类成员原则 : 无论虚基类与产生对象的派生类相隔多远, 先调用虚基类的构造函数, 再按继承次序调用直接基类的构造函数 1 class B0 2 { 3 public: 4 int nv0; 5 void fun() 6 { cout<<"member of B0\n"; } 7 }; 8 class B1: virtual public B0 9 { 10 public: 11 int nv1; 12 }; 13 class B2: virtual public B0 14 { 15 public: 16 int nv2; 17 }; 18 class D1: public B1, public B2 19 { 20 public: 21 int nvd; 22 void fun() // 隐藏基类同名函数 23 { cout<<"member of D1\n"; } 24 }; 25 int main() 26 { 27 D1 d1; 28 d1.nv0=2; // 使用最远基类成员 29 d1.fun(); 30 return 0; 31 } 运行结果 : Member of D1 当产生对象 D1 时, 构造函数调用次序 :B0() B1() B2() Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

44 虚基类与构造函数虚 (virtual) 基类和赋值兼容 最远基类成员原则 : 无论虚基类与产生对象的派生类相隔多远, 先调用虚基类的构造函数, 再按继承次序调用直接基类的构造函数 1 class B0 2 { 3 public: 4 int nv0; 5 void fun() 6 { cout<<"member of B0\n"; } 7 }; 8 class B1: virtual public B0 9 { 10 public: 11 int nv1; 12 }; 13 class B2: virtual public B0 14 { 15 public: 16 int nv2; 17 }; 18 class D1: public B1, public B2 19 { 20 public: 21 int nvd; 22 void fun() // 隐藏基类同名函数 23 { cout<<"member of D1\n"; } 24 }; 25 int main() 26 { 27 D1 d1; 28 d1.nv0=2; // 使用最远基类成员 29 d1.fun(); 30 return 0; 31 } 运行结果 : Member of D1 当产生对象 D1 时, 构造函数调用次序 :B0() B1() B2() D1() Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

45 虚基类与构造函数虚 (virtual) 基类和赋值兼容 最远基类成员原则 : 无论虚基类与产生对象的派生类相隔多远, 先调用虚基类的构造函数, 再按继承次序调用直接基类的构造函数 1 class B0 2 { 3 public: 4 int nv0; 5 void fun() 6 { cout<<"member of B0\n"; } 7 }; 8 class B1: virtual public B0 9 { 10 public: 11 int nv1; 12 }; 13 class B2: virtual public B0 14 { 15 public: 16 int nv2; 17 }; 18 class D1: public B1, public B2 19 { 20 public: 21 int nvd; 22 void fun() // 隐藏基类同名函数 23 { cout<<"member of D1\n"; } 24 }; 25 int main() 26 { 27 D1 d1; 28 d1.nv0=2; // 使用最远基类成员 29 d1.fun(); 30 return 0; 31 } 运行结果 : Member of D1 当产生对象 D1 时, 构造函数调用次序 :B0() B1() B2() D1() 此时, 调用的是基类与派生类的默认构造函数 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

46 虚基类与构造函数虚 (virtual) 基类和赋值兼容 请写出如下多重继承中构造函数的调用顺序 1 class base1 2 { 3 }; 4 class base2 5 { 6 }; 7 class level1 : public base2, virtual public base1 // 8 { 9 }; 10 class level2 : public base2, virtual public base1 // 11 { 12 }; 13 class toplevel1 : public level1, virtual public level2 14 { 15 }; 16 toplevel1 view; 当产生对象 view 时, 函数调用次序 : Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

47 虚基类与构造函数虚 (virtual) 基类和赋值兼容 请写出如下多重继承中构造函数的调用顺序 1 class base1 2 { 3 }; 4 class base2 5 { 6 }; 7 class level1 : public base2, virtual public base1 // 8 { 9 }; 10 class level2 : public base2, virtual public base1 // 11 { 12 }; 13 class toplevel1 : public level1, virtual public level2 14 { 15 }; 16 toplevel1 view; 当产生对象 view 时, 函数调用次序 : base1() base2() Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

48 虚基类与构造函数虚 (virtual) 基类和赋值兼容 请写出如下多重继承中构造函数的调用顺序 1 class base1 2 { 3 }; 4 class base2 5 { 6 }; 7 class level1 : public base2, virtual public base1 // 8 { 9 }; 10 class level2 : public base2, virtual public base1 // 11 { 12 }; 13 class toplevel1 : public level1, virtual public level2 14 { 15 }; 16 toplevel1 view; 当产生对象 view 时, 函数调用次序 : base1() base2() level2() Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

49 虚基类与构造函数虚 (virtual) 基类和赋值兼容 请写出如下多重继承中构造函数的调用顺序 1 class base1 2 { 3 }; 4 class base2 5 { 6 }; 7 class level1 : public base2, virtual public base1 // 8 { 9 }; 10 class level2 : public base2, virtual public base1 // 11 { 12 }; 13 class toplevel1 : public level1, virtual public level2 14 { 15 }; 16 toplevel1 view; 当产生对象 view 时, 函数调用次序 : base1() base2() level2() base2() Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

50 虚基类与构造函数虚 (virtual) 基类和赋值兼容 请写出如下多重继承中构造函数的调用顺序 1 class base1 2 { 3 }; 4 class base2 5 { 6 }; 7 class level1 : public base2, virtual public base1 // 8 { 9 }; 10 class level2 : public base2, virtual public base1 // 11 { 12 }; 13 class toplevel1 : public level1, virtual public level2 14 { 15 }; 16 toplevel1 view; 当产生对象 view 时, 函数调用次序 : base1() base2() level2() base2() level1() toplevel1() Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

51 虚基类与构造函数虚 (virtual) 基类和赋值兼容 请写出如下多重继承中构造函数的调用顺序 1 class base1 2 { 3 }; 4 class base2 5 { 6 }; 7 class level1 : public base2, virtual public base1 // 8 { 9 }; 10 class level2 : public base2, virtual public base1 // base1 是虚基类, 在这 里执行其构造函数 11 { 12 }; 13 class toplevel1 : public level1, virtual public level2 14 { 15 }; 16 toplevel1 view; 当产生对象 view 时, 函数调用次序 : base1() base2() level2() base2() level1() toplevel1() Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

52 虚基类与构造函数虚 (virtual) 基类和赋值兼容 请写出如下多重继承中构造函数的调用顺序 1 class base1 2 { 3 }; 4 class base2 5 { 6 }; 7 class level1 : public base2, virtual public base1 // base1 是虚基类, 无需再执行其构造函数 8 { 9 }; 10 class level2 : public base2, virtual public base1 // base1 是虚基类, 在这里执行其构造函数 11 { 12 }; 13 class toplevel1 : public level1, virtual public level2 14 { 15 }; 16 toplevel1 view; 当产生对象 view 时, 函数调用次序 : base1() base2() level2() base2() level1() toplevel1() Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

53 提纲 赋值兼容及其限制 1 访问冲突 2 支配规则 3 虚基类与构造函数 4 赋值兼容及其限制 5 总结与思考 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

54 赋值兼容及其限制赋值兼容及其限制 赋值 赋值兼容规则不同类型数据之间在一定条件下可以进行自动转换和赋值, 这称为赋值兼容 例如 1 int to double 在赋值之前, 把整型数据先转换成为双精度型数据, 但是不能把一个整型数据赋给指针变量 基类与派生类对象之间是否也有赋值兼容的关系, 可否进行类型间的转换? Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

55 赋值兼容及其限制赋值兼容及其限制 赋值 赋值兼容规则不同类型数据之间在一定条件下可以进行自动转换和赋值, 这称为赋值兼容 例如 1 int to double 在赋值之前, 把整型数据先转换成为双精度型数据, 但是不能把一个整型数据赋给指针变量 基类与派生类对象之间是否也有赋值兼容的关系, 可否进行类型间的转换? 基类与派生类对象之间有赋值兼容关系 因此, 可将派生类的值赋给基类对象, 在用到基类对象时可以用其子类对象代替 具体表现在以下几个方面 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

56 赋值兼容及其限制赋值兼容及其限制 赋值 赋值兼容规则不同类型数据之间在一定条件下可以进行自动转换和赋值, 这称为赋值兼容 例如 1 int to double 在赋值之前, 把整型数据先转换成为双精度型数据, 但是不能把一个整型数据赋给指针变量 基类与派生类对象之间是否也有赋值兼容的关系, 可否进行类型间的转换? 基类与派生类对象之间有赋值兼容关系 因此, 可将派生类的值赋给基类对象, 在用到基类对象时可以用其子类对象代替 具体表现在以下几个方面 派生类对象可以向基类对象赋值 可以用子类 ( 即公用派生类 ) 对象对其基类对象赋值 如 1 A a1; // 定义基类 A 对象 a1 2 B b1; // 定义类 A 的公用派生类 B 的对象 b1 3 a1=b1; // 用派生类 B 对象 b1 对基类对象 a1 赋值 实际上, 赋值只是对数据成员赋值, 类的成员函数不存在赋值问题 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

57 赋值兼容及其限制赋值兼容及其限制 引用 派生类对象可以替代基类对象向基类对象的引用进行赋值或初始化 例如, 已定义了基类 A 派生类 B 以及基类对象 a1, 可以定义 a1 的引用变量 : 1 A a1; // 定义基类 A 对象 a1 2 B b1; // 定义公用派生类 B 对象 b1 3 A& r=a1; // 定义基类 A 对象的引用变量 r, 并用 a1 对其初始化 这时, 引用变量 r 是 a1 的别名,r 和 a1 共享同一段存储单元 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

58 赋值兼容及其限制赋值兼容及其限制 引用 派生类对象可以替代基类对象向基类对象的引用进行赋值或初始化 例如, 已定义了基类 A 派生类 B 以及基类对象 a1, 可以定义 a1 的引用变量 : 1 A a1; // 定义基类 A 对象 a1 2 B b1; // 定义公用派生类 B 对象 b1 3 A& r=a1; // 定义基类 A 对象的引用变量 r, 并用 a1 对其初始化 这时, 引用变量 r 是 a1 的别名,r 和 a1 共享同一段存储单元 我们也可以用派生类的对象初始化引用变量 r, 即把上面最后一行改为 3 A& r=b1; // 定义基类 A 对象的引用变量 r, 并用派生类 B 对象 b1 对其初始化 或者保留上面第 3 行 A& r=a1;, 并对 r 重新赋值 4 r=b1; // 用派生类 B 对象 b1 对 a1 的引用变量 r 赋值 此时,r 并不是 b1 的别名, 也不与 b1 共享同一段存储单元 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

59 赋值兼容及其限制赋值兼容及其限制 引用 派生类对象可以替代基类对象向基类对象的引用进行赋值或初始化 例如, 已定义了基类 A 派生类 B 以及基类对象 a1, 可以定义 a1 的引用变量 : 1 A a1; // 定义基类 A 对象 a1 2 B b1; // 定义公用派生类 B 对象 b1 3 A& r=a1; // 定义基类 A 对象的引用变量 r, 并用 a1 对其初始化 这时, 引用变量 r 是 a1 的别名,r 和 a1 共享同一段存储单元 我们也可以用派生类的对象初始化引用变量 r, 即把上面最后一行改为 3 A& r=b1; // 定义基类 A 对象的引用变量 r, 并用派生类 B 对象 b1 对其初始化 或者保留上面第 3 行 A& r=a1;, 并对 r 重新赋值 4 r=b1; // 用派生类 B 对象 b1 对 a1 的引用变量 r 赋值 此时,r 并不是 b1 的别名, 也不与 b1 共享同一段存储单元 需要注意的是 :r 只是 b1 中基类部分的别名,r 与 b1 中基类部分共享同一段存储单元,r 与 b1 具有相同的起始地址 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

60 赋值兼容及其限制赋值兼容及其限制 引用 如果函数的参数是基类对象或基类对象的引用, 相应的函数实参可以使用派生类的对象 例如, 已定义了基类 A 派生类 B, 有一函数 1 void fun(a& r) // 形参是类 A 的对象的引用变量 2 { 3 cout<<r.num<<endl; // 输出该引用变量的数据成员 num 4 } 函数的形参是类 A 的对象的引用变量, 函数 fun 的实参应该为 A 类的对象 5 fun(a1); // 此处,a1 为类 A 的对象 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

61 赋值兼容及其限制赋值兼容及其限制 引用 如果函数的参数是基类对象或基类对象的引用, 相应的函数实参可以使用派生类的对象 例如, 已定义了基类 A 派生类 B, 有一函数 1 void fun(a& r) // 形参是类 A 的对象的引用变量 2 { 3 cout<<r.num<<endl; // 输出该引用变量的数据成员 num 4 } 函数的形参是类 A 的对象的引用变量, 函数 fun 的实参应该为 A 类的对象 5 fun(a1); // 此处,a1 为类 A 的对象 由于基类对象与派生类对象赋值兼容, 派生类的对象能自动转换类型, 在调用 fun 函数时可以用派生类 B 的对象 b1 作实参 : 6 fun(b1); 输出类 B 的对象 b1 的基类数据成员 num 的值 与前相同, 在 fun 函数中只能访问派生类中继承自基类的成员 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

62 赋值兼容及其限制赋值兼容及其限制 引用 派生类对象初始化基类的引用, 引用是派生类继承自基类部分成员的别名 1 class Base { 2 public: 3 Base() { cout<<"base"<<endl; } 4 void fun() { cout<<"base::fun()" <<endl; } 5 private: 6 int x; 7 }; 8 class Derive : public Base{ 9 public: 10 Derive() { cout<<"derive"<<endl; } 11 void fun() { cout<<"derive::fun()" <<endl; } 12 void show() { cout<<"derive::show()"<<endl; } 13 private: 14 int y; 15 }; 16 int main() { 17 Derive d; Base & b=d; b.fun(); // 18 b.show(); // 19 return 0; 20 } Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

63 赋值兼容及其限制赋值兼容及其限制 引用 派生类对象初始化基类的引用, 引用是派生类继承自基类部分成员的别名 1 class Base { 2 public: 3 Base() { cout<<"base"<<endl; } 4 void fun() { cout<<"base::fun()" <<endl; } 5 private: 6 int x; 7 }; 8 class Derive : public Base{ 9 public: 10 Derive() { cout<<"derive"<<endl; } 11 void fun() { cout<<"derive::fun()" <<endl; } 12 void show() { cout<<"derive::show()"<<endl; } 13 private: 14 int y; 15 }; 16 int main() { 17 Derive d; Base & b=d; b.fun(); // 正确 18 b.show(); // 错误 : 19 return 0; 20 } Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

64 赋值兼容及其限制赋值兼容及其限制 引用 派生类对象初始化基类的引用, 引用是派生类继承自基类部分成员的别名 1 class Base { 2 public: 3 Base() { cout<<"base"<<endl; } 4 void fun() { cout<<"base::fun()" <<endl; } 5 private: 6 int x; 7 }; 8 class Derive : public Base{ 9 public: 10 Derive() { cout<<"derive"<<endl; } 11 void fun() { cout<<"derive::fun()" <<endl; } 12 void show() { cout<<"derive::show()"<<endl; } 13 private: 14 int y; 15 }; 16 int main() { 17 Derive d; Base & b=d; b.fun(); // 正确 18 b.show(); // 错误 : 派生类对象可初始化基类引用, 但不能访问非继承自基类的成员 19 return 0; 20 } Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

65 赋值兼容及其限制赋值兼容及其限制 引用 派生类对象初始化基类的引用, 引用是派生类继承自基类部分成员的别名 1 class Base { 2 public: 3 Base() { cout<<"base"<<endl; } 4 void fun() { cout<<"base::fun()" <<endl; } 5 private: 6 int x; 7 }; 8 class Derive : public Base{ 9 public: 10 Derive() { cout<<"derive"<<endl; } 11 void fun() { cout<<"derive::fun()" <<endl; } 12 void show() { cout<<"derive::show()"<<endl; } 13 private: 14 int y; 15 }; 16 int main() { 17 Derive d; Base & b=d; b.fun(); // 正确 18 b.show(); // 错误 : 派生类对象可初始化基类引用, 但不能访问非继承自基类的成员如果删除错误之处 19 return 0;, 则运行结果为 : 20 } Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

66 赋值兼容及其限制赋值兼容及其限制 引用 派生类对象初始化基类的引用, 引用是派生类继承自基类部分成员的别名 1 class Base { 2 public: 3 Base() { cout<<"base"<<endl; } 4 void fun() { cout<<"base::fun()" <<endl; } 5 private: 6 int x; 7 }; 8 class Derive : public Base{ 9 public: 10 Derive() { cout<<"derive"<<endl; } 11 void fun() { cout<<"derive::fun()" <<endl; } 12 void show() { cout<<"derive::show()"<<endl; } 13 private: 14 int y; 15 }; 16 int main() { 17 Derive d; Base & b=d; b.fun(); // 正确 18 b.show(); // 错误 : 派生类对象可初始化基类引用, 但不能访问非继承自基类的成员 如果删除错误之处 19 return 0;, 则运行结果为 :Base 20 } Derive Base::fun() Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

67 赋值兼容及其限制赋值兼容及其限制 指针 派生类对象的地址可以赋给指向基类对象的指针变量, 即 : 指向基类对象的指针变量也可以指向派生类对象 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

68 赋值兼容及其限制赋值兼容及其限制 指针 派生类对象的地址可以赋给指向基类对象的指针变量, 即 : 指向基类对象的指针变量也可以指向派生类对象 普通方式 : 1 class Base 2 { 3 public: 4 void Demon() { cout << "This is Father Demon!" << endl; } 5 void Display (){ cout << "This is Father Display!" << endl; } 6 }; 7 class SubBase : public Base 8 { 9 public: 10 void Demon() { cout << "This is Derived Demon!" << endl; } 11 void Display() { cout << "This is Derived Display!" << endl; } 12 }; 13 int main() 14 { 15 Base * inst = new SubBase(); inst->demon(); inst->display(); 16 return 0; 17 } 运行结果 : Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

69 赋值兼容及其限制赋值兼容及其限制 指针 派生类对象的地址可以赋给指向基类对象的指针变量, 即 : 指向基类对象的指针变量也可以指向派生类对象 普通方式 : 1 class Base 2 { 3 public: 4 void Demon() { cout << "This is Father Demon!" << endl; } 5 void Display (){ cout << "This is Father Display!" << endl; } 6 }; 7 class SubBase : public Base 8 { 9 public: 10 void Demon() { cout << "This is Derived Demon!" << endl; } 11 void Display() { cout << "This is Derived Display!" << endl; } 12 }; 13 int main() 14 { 15 Base * inst = new SubBase(); inst->demon(); inst->display(); 16 return 0; 17 } 运行结果 : This is Father Demon! This is Father Display! Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

70 赋值兼容及其限制赋值兼容及其限制 指针 派生类对象的地址可以赋给指向基类对象的指针变量, 即 : 指向基类对象的指针变量也可以指向派生类对象 多态方式 : 1 class Base 2 { 3 public: 4 virtual void Demon() { cout << "This is Father Demon!" << endl; } 5 virtual void Display (){ cout << "This is Father Display!"<< endl; } 6 }; 7 class SubBase : public Base 8 { 9 public: 10 void Demon() { cout << "This is Derived Demon!" << endl; } 11 void Display() { cout << "This is Derived Display!" << endl; } 12 }; 13 int main() 14 { 15 Base * inst = new SubBase(); inst->demon(); inst->display(); 16 return 0; 17 } 运行结果 : Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

71 赋值兼容及其限制赋值兼容及其限制 指针 派生类对象的地址可以赋给指向基类对象的指针变量, 即 : 指向基类对象的指针变量也可以指向派生类对象 多态方式 : 1 class Base 2 { 3 public: 4 virtual void Demon() { cout << "This is Father Demon!" << endl; } 5 virtual void Display (){ cout << "This is Father Display!"<< endl; } 6 }; 7 class SubBase : public Base 8 { 9 public: 10 void Demon() { cout << "This is Derived Demon!" << endl; } 11 void Display() { cout << "This is Derived Display!" << endl; } 12 }; 13 int main() 14 { 15 Base * inst = new SubBase(); inst->demon(); inst->display(); 16 return 0; 17 } 运行结果 : This is Derived Demon! This is Derived Display! Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

72 赋值兼容及其限制赋值兼容及其限制 指针 派生类对象的地址可以赋给指向基类对象的指针变量, 即 : 指向基类对象的指针变量也可以指向派生类对象 多态方式 : 1 class Shape{ 2 public: 3 virtual double area() const = 0; 4 }; 5 class Square : public Shape { 6 double size; 7 public: 8 Square(double s) 9 { size = s; } 10 virtual double area() const 11 { return size * size; } 12 }; 13 class Circle : public Shape { 14 double R; 15 public: 16 Circle(double r) 17 { radius = r; } 18 virtual double area() const 19 { return *R*R; } 20 }; 21 int main() 22 { 23 Shape * ps[2]; // 基类指针数组 24 Square Squ(2.0); 25 Circle Cir(1.0); 26 ps[0] = &Squ; 27 ps[1] = &Cir; 28 for (int i = 0; i < 2; i++) 29 {cout<<ps[i]->area()<<"\n";} 30 return 0; 31 } 运行结果 : Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

73 赋值兼容及其限制赋值兼容及其限制 指针 派生类对象的地址可以赋给指向基类对象的指针变量, 即 : 指向基类对象的指针变量也可以指向派生类对象 多态方式 : 1 class Shape{ 2 public: 3 virtual double area() const = 0; 4 }; 5 class Square : public Shape { 6 double size; 7 public: 8 Square(double s) 9 { size = s; } 10 virtual double area() const 11 { return size * size; } 12 }; 13 class Circle : public Shape { 14 double R; 15 public: 16 Circle(double r) 17 { radius = r; } 18 virtual double area() const 19 { return *R*R; } 20 }; 21 int main() 22 { 23 Shape * ps[2]; // 基类指针数组 24 Square Squ(2.0); 25 Circle Cir(1.0); 26 ps[0] = &Squ; 27 ps[1] = &Cir; 28 for (int i = 0; i < 2; i++) 29 {cout<<ps[i]->area()<<"\n";} 30 return 0; 31 } 运行结果 : Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

74 赋值兼容及其限制赋值兼容及其限制 指针 派生类对象的地址可以赋给指向基类对象的指针变量, 即 : 指向基类对象的指针变量也可以指向派生类对象 动态联编 : 1 class Shape{ 2 public: 3 virtual double area() const = 0; 4 }; 5 class Square : public Shape { 6 double size; 7 public: 8 Square(double s) 9 { size = s; } 10 virtual double area() const 11 { return size * size; } 12 }; 13 class Circle : public Shape { 14 double R; 15 public: 16 Circle(double r) 17 { radius = r; } 18 virtual double area() const 19 { return *R*R; } 20 }; 21 int main() 22 { 23 Shape * ps[2]; // 基类指针数组 24 Square Squ(2.0); 25 Circle Cir(1.0); 26 ps[0] = &Squ; 27 ps[1] = &Cir; 28 for (int i = 0; i < 2; i++) 29 {cout<<ps[i]->area()<<"\n";} 30 return 0; 31 } 运行结果 : 基类指针指向派生类对象 这可以实现运行时的多态性 ( 也称为动态联编 ) Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

75 赋值兼容及其限制赋值兼容及其限制 指针 派生类对象的地址可以赋给指向基类对象的指针变量, 即 : 指向基类对象的指针变量也可以指向派生类对象 动态联编 : 1 class Shape{ 18 virtual double area() const 2 public: 19 { return *R*R; } 3 virtual double area() const 20 }; = 0; 21 int main() 4 }; 22 { 5 class Square : public Shape { 23 Shape * ps[2]; // 基类指针数组 6 double size; 24 Square Squ(2.0); 7 public: 25 Circle Cir(1.0); 8 Square(double s) 26 ps[0] = &Squ; 9 { size = s; } 27 ps[1] = &Cir; 10 virtual double area() const 28 for (int i = 0; i < 2; i++) 11 { return size * size; } 29 {cout<<ps[i]->area()<<"\n";} 12 }; 30 return 0; 13 class Circle : public Shape { 31 } 14 double R; 运行结果 : 15 public: 4 16 Circle(double r) 注意 :{ 使用基类指针或引用时 radius = r; }, 只允许访问从相应基类中继承来的成员, 基类指针指向派生类对象 这可以实现运行时的多态性不允许访问其他基类的成员或派生类新增加的成员 ( 也称为动态联编 ) Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

76 赋值兼容及其限制赋值兼容及其限制 例程 定义一个基类 Student, 再定义由 Student 类的公有派生出的类 Graduate 类 Student 设 num( 学号 ) name( 名字 ) 和 score( 成绩 )3 个数据和函数 display() 在 Graduate 类只增加一个数据成员 pay( 工资 ) 和成员函数 display() 用指向基类 Student 的指针变量访问派生类 Graduate 对象的数据 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

77 赋值兼容及其限制赋值兼容及其限制 例程 定义一个基类 Student, 再定义由 Student 类的公有派生出的类 Graduate 类 Student 设 num( 学号 ) name( 名字 ) 和 score( 成绩 )3 个数据和函数 display() 在 Graduate 类只增加一个数据成员 pay( 工资 ) 和成员函数 display() 用指向基类 Student 的指针变量访问派生类 Graduate 对象的数据 1 class Student { 2 public: 3 Student(int,string,float); 4 void display( ); 5 private: 6 int num; string name; float score; 7 }; 8 class Graduate : public Student{ 9 public: 10 Graduate(int,string,float, float); 11 void display( ); 12 private: 13 float payment; // 工资 14 }; Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

78 赋值兼容及其限制赋值兼容及其限制 例程 定义一个基类 Student, 再定义由 Student 类的公有派生出的类 Graduate 类 Student 设 num( 学号 ) name( 名字 ) 和 score( 成绩 )3 个数据和函数 display() 在 Graduate 类只增加一个数据成员 pay( 工资 ) 和成员函数 display() 用指向基类 Student 的指针变量访问派生类 Graduate 对象的数据 1 class Student { 2 public: 3 Student(int,string,float); 4 void display( ); 5 private: 6 int num; string name; float score; 7 }; 8 class Graduate : public Student{ 9 public: 10 Graduate(int,string,float, float); 11 void display( ); 12 private: 13 float payment; // 工资 14 }; 15 int main() { 16 Student stud1(1001, "XiaoWu", 99.5); 17 Graduate grad1(2001, "XiaoLi", 95.5, 1200); 18 Student *pt = &stud1; // 定义指向 Student 类对象的指针并指向 stud1 19 pt->display( );...;...; 20 } Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

79 赋值兼容及其限制赋值兼容及其限制 例程 定义一个基类 Student, 再定义由 Student 类的公有派生出的类 Graduate 1 #include <iostream> 2 #include <string> 3 using namespace std; 4 class Student // 声明 Student 类 5 { 6 public: 7 Student(int, string,float); // 声明构造函数 8 void display( ); // 声明输出函数 9 private: 10 int num; 11 string name; 12 float score; 13 }; 14 Student::Student(int n, string nam,float s) // 定义构造函数 15 { 16 num=n; 17 name=nam; 18 score=s; 19 } 20 void Student::display( ) // 定义输出函数 21 { Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

80 赋值兼容及其限制赋值兼容及其限制 例程 22 cout<<endl<<"num:"<<num<<endl; 23 cout<<"name:"<<name<<endl; 24 cout<<"score:"<<score<<endl; 25 } 26 class Graduate:public Student // 声明公用派生类 Graduate 27 { 28 public: 29 Graduate(int, string,float,float); // 声明构造函数 30 void display( ); // 声明输出函数 31 private: 32 float pay; // 工资 33 }; 34 // 定义构造函数 35 Graduate::Graduate(int n, string nam,float s,float p):student(n,nam,s), pay(p) 36 { } 37 void Graduate::display() // 定义输出函数 38 { 39 Student::display(); // 调用 Student 类的 display 函数 40 cout<<"pay="<<pay<<endl; 41 } 42 int main() Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

81 赋值兼容及其限制赋值兼容及其限制 例程 43 { 44 Student stud1(1001, "XiaoWu", 99.5); //Student 的对象 45 Graduate grad1(2001, "XiaoLi", 95.5, 1200); //Graduate 的对象 46 Student *pt=&stud1; // 指向 Student 类对象的指针并指向 stud1 47 pt->display( ); // 调用 stud1.display 函数 48 pt=&grad1; // 指针指向 grad1 49 pt->display( ); // 调用 grad1.display 函数 50 } Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

82 赋值兼容及其限制赋值兼容及其限制 例程 43 { 44 Student stud1(1001, "XiaoWu", 99.5); //Student 的对象 45 Graduate grad1(2001, "XiaoLi", 95.5, 1200); //Graduate 的对象 46 Student *pt=&stud1; // 指向 Student 类对象的指针并指向 stud1 47 pt->display( ); // 调用 stud1.display 函数 48 pt=&grad1; // 指针指向 grad1 49 pt->display( ); // 调用 grad1.display 函数 50 } 程序输出结果为 : num:1001 name:li score:99.5 num:2001 name:wang score:95.5 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

83 赋值兼容及其限制赋值兼容及其限制 例程 43 { 44 Student stud1(1001, "XiaoWu", 99.5); //Student 的对象 45 Graduate grad1(2001, "XiaoLi", 95.5, 1200); //Graduate 的对象 46 Student *pt=&stud1; // 指向 Student 类对象的指针并指向 stud1 47 pt->display( ); // 调用 stud1.display 函数 48 pt=&grad1; // 指针指向 grad1 49 pt->display( ); // 调用 grad1.display 函数 50 } 程序输出结果为 : num:1001 name:li score:99.5 num:2001 name:wang score:95.5 由此程序可知 : 用指向基类对象的指针变量指向派生类对象是完全合法且安全的, 不会出现编译上的错误 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

84 赋值兼容及其限制赋值兼容及其限制 例程 43 { 44 Student stud1(1001, "XiaoWu", 99.5); //Student 的对象 45 Graduate grad1(2001, "XiaoLi", 95.5, 1200); //Graduate 的对象 46 Student *pt=&stud1; // 指向 Student 类对象的指针并指向 stud1 47 pt->display( ); // 调用 stud1.display 函数 48 pt=&grad1; // 指针指向 grad1 49 pt->display( ); // 调用 grad1.display 函数 50 } 程序输出结果为 : num:1001 name:li score:99.5 num:2001 name:wang score:95.5 由此程序可知 : 用指向基类对象的指针变量指向派生类对象是完全合法且安全的, 不会出现编译上的错误 当希望通过使用基类指针调用派生类对象的成员时, 就要使用虚函数和多态性 ( 这些特性将在后面的章节中介绍 ) Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

85 提纲 总结与思考 1 访问冲突 2 支配规则 3 虚基类与构造函数 4 赋值兼容及其限制 5 总结与思考 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

86 总结与思考 总结与思考 访问冲突与二义性 什么是多重继承中的访问冲突 ( 二义性问题 )? 发生二义性问题有哪两种情况? 如何解决访问冲突? Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

87 总结与思考 总结与思考 访问冲突与二义性什么是多重继承中的访问冲突 ( 二义性问题 )? 发生二义性问题有哪两种情况? 如何解决访问冲突? 支配规则什么是支配规则? 支配规则在什么情况下起作用? 什么是同名隐藏? Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

88 总结与思考 总结与思考 访问冲突与二义性 什么是多重继承中的访问冲突 ( 二义性问题 )? 发生二义性问题有哪两种情况? 如何解决访问冲突? 支配规则 什么是支配规则? 支配规则在什么情况下起作用? 什么是同名隐藏? 虚基类及其特点 当在多条继承路径上有一个公共的基类, 在这些路径的某几条汇合处, 这个公共的基类就会产生多个实例 ( 或副本 ), 若只想保存这个基类的一个实例, 可以将这个公共基类说明为虚基类 虚基类构造函数的参数必须由最新派生出来的类负责初始化 ( 即使不是直接继承 ); 虚基类的构造函数先于非虚基类的构造函数执行 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

89 总结与思考 总结与思考 访问冲突与二义性 什么是多重继承中的访问冲突 ( 二义性问题 )? 发生二义性问题有哪两种情况? 如何解决访问冲突? 支配规则 什么是支配规则? 支配规则在什么情况下起作用? 什么是同名隐藏? 虚基类及其特点 当在多条继承路径上有一个公共的基类, 在这些路径的某几条汇合处, 这个公共的基类就会产生多个实例 ( 或副本 ), 若只想保存这个基类的一个实例, 可以将这个公共基类说明为虚基类 虚基类构造函数的参数必须由最新派生出来的类负责初始化 ( 即使不是直 接继承 ); 虚基类的构造函数先于非虚基类的构造函数执行 class Ancestor { }; class Father : virtual public Ancestor{ }; class Mother : virtual public Ancestor{ }; class Child : public Father, public Mother{ }; 在类 Child 的对象中, 仅有类 Ancestor 的一个对象数据 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

90 总结与思考 总结与思考 赋值兼容及其限制 可将公有派生类的对象赋值给基类的对象, 就像把派生类对象新定义的成员切割 / 切除后赋给基类的对象 ; Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

91 总结与思考 总结与思考 赋值兼容及其限制 可将公有派生类的对象赋值给基类的对象, 就像把派生类对象新定义的成员切割 / 切除后赋给基类的对象 ; 不允许将基类的对象赋值给派生类的对象 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

92 总结与思考 总结与思考 赋值兼容及其限制 可将公有派生类的对象赋值给基类的对象, 就像把派生类对象新定义的成员切割 / 切除后赋给基类的对象 ; 不允许将基类的对象赋值给派生类的对象 赋值兼容及其限制可归结为 : 1 可以将派生类对象赋值给基类对象 : 系统将派生类对象中从基类继承来的成员赋给基类对象的成员 2 不能将基类对象赋值给派生类对象 : 基类中的成员变量必然少于派生类, 派生类新定义的成员变量不可无值可赋 3 私有或保护派生类的对象不能够赋值给基类的对象 : 派生类不能够突破关键词 private 或 protected 所限定的访问权限 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

93 总结与思考 总结与思考 赋值兼容及其限制 可将公有派生类的对象赋值给基类的对象, 就像把派生类对象新定义的成员切割 / 切除后赋给基类的对象 ; 不允许将基类的对象赋值给派生类的对象 赋值兼容及其限制可归结为 : 1 可以将派生类对象赋值给基类对象 : 系统将派生类对象中从基类继承来的成员赋给基类对象的成员 2 不能将基类对象赋值给派生类对象 : 基类中的成员变量必然少于派生类, 派生类新定义的成员变量不可无值可赋 3 私有或保护派生类的对象不能够赋值给基类的对象 : 派生类不能够突破关键词 private 或 protected 所限定的访问权限 4 可将派生类对象的地址赋给基类类型的指针变量, 例如 Base *ptr = &der_obj 5 派生类的对象可初始化基类类型的引用, 例如 Base &ref = der_obj Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

94 总结与思考 总结与思考 赋值兼容及其限制 可将公有派生类的对象赋值给基类的对象, 就像把派生类对象新定义的成员切割 / 切除后赋给基类的对象 ; 不允许将基类的对象赋值给派生类的对象 赋值兼容及其限制可归结为 : 1 可以将派生类对象赋值给基类对象 : 系统将派生类对象中从基类继承来的成员赋给基类对象的成员 2 不能将基类对象赋值给派生类对象 : 基类中的成员变量必然少于派生类, 派生类新定义的成员变量不可无值可赋 3 私有或保护派生类的对象不能够赋值给基类的对象 : 派生类不能够突破关键词 private 或 protected 所限定的访问权限 4 可将派生类对象的地址赋给基类类型的指针变量, 例如 Base *ptr = &der_obj 5 派生类的对象可初始化基类类型的引用, 例如 Base &ref = der_obj Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

95 总结与思考 总结与思考 赋值兼容及其限制 可将公有派生类的对象赋值给基类的对象, 就像把派生类对象新定义的成员切割 / 切除后赋给基类的对象 ; 不允许将基类的对象赋值给派生类的对象 赋值兼容及其限制可归结为 : 1 可以将派生类对象赋值给基类对象 : 系统将派生类对象中从基类继承来的成员赋给基类对象的成员 2 不能将基类对象赋值给派生类对象 : 基类中的成员变量必然少于派生类, 派生类新定义的成员变量不可无值可赋 3 私有或保护派生类的对象不能够赋值给基类的对象 : 派生类不能够突破关键词 private 或 protected 所限定的访问权限 4 可将派生类对象的地址赋给基类类型的指针变量, 例如 Base *ptr = &der_obj 5 派生类的对象可初始化基类类型的引用, 例如 Base &ref = der_obj Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

96 总结与思考 总结与思考 赋值兼容及其限制 可将公有派生类的对象赋值给基类的对象, 就像把派生类对象新定义的成员切割 / 切除后赋给基类的对象 ; 不允许将基类的对象赋值给派生类的对象 赋值兼容及其限制可归结为 : 1 可以将派生类对象赋值给基类对象 : 系统将派生类对象中从基类继承来的成员赋给基类对象的成员 2 不能将基类对象赋值给派生类对象 : 基类中的成员变量必然少于派生类, 派生类新定义的成员变量不可无值可赋 3 私有或保护派生类的对象不能够赋值给基类的对象 : 派生类不能够突破关键词 private 或 protected 所限定的访问权限 4 可将派生类对象的地址赋给基类类型的指针变量, 例如 Base *ptr = &der_obj 5 派生类的对象可初始化基类类型的引用, 例如 Base &ref = der_obj Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

97 总结与思考 总结与思考 赋值兼容及其限制 可将公有派生类的对象赋值给基类的对象, 就像把派生类对象新定义的成员切割 / 切除后赋给基类的对象 ; 不允许将基类的对象赋值给派生类的对象 赋值兼容及其限制可归结为 : 1 可以将派生类对象赋值给基类对象 : 系统将派生类对象中从基类继承来的成员赋给基类对象的成员 2 不能将基类对象赋值给派生类对象 : 基类中的成员变量必然少于派生类, 派生类新定义的成员变量不可无值可赋 3 私有或保护派生类的对象不能够赋值给基类的对象 : 派生类不能够突破关键词 private 或 protected 所限定的访问权限 4 可将派生类对象的地址赋给基类类型的指针变量, 例如 Base *ptr = &der_obj 5 派生类的对象可初始化基类类型的引用, 例如 Base &ref = der_obj Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

98 总结与思考 总结与思考 赋值兼容及其限制 可将公有派生类的对象赋值给基类的对象, 就像把派生类对象新定义的成员切割 / 切除后赋给基类的对象 ; 不允许将基类的对象赋值给派生类的对象 赋值兼容及其限制可归结为 : 1 可以将派生类对象赋值给基类对象 : 系统将派生类对象中从基类继承来的成员赋给基类对象的成员 2 不能将基类对象赋值给派生类对象 : 基类中的成员变量必然少于派生类, 派生类新定义的成员变量不可无值可赋 3 私有或保护派生类的对象不能够赋值给基类的对象 : 派生类不能够突破关键词 private 或 protected 所限定的访问权限 4 可将派生类对象的地址赋给基类类型的指针变量, 例如 Base *ptr = &der_obj 5 派生类的对象可初始化基类类型的引用, 例如 Base &ref = der_obj 在使用基类类型的指针变量或引用时 : 只允许访问从相应基类中继承来的成员, 不允许访问其他基类的成员或派生类新增加的成员 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

99 总结与思考 总结与思考 赋值兼容及其限制 可将公有派生类的对象赋值给基类的对象, 就像把派生类对象新定义的成员切割 / 切除后赋给基类的对象 ; 不允许将基类的对象赋值给派生类的对象 赋值兼容及其限制可归结为 : 1 可以将派生类对象赋值给基类对象 : 系统将派生类对象中从基类继承来的成员赋给基类对象的成员 2 不能将基类对象赋值给派生类对象 : 基类中的成员变量必然少于派生类, 派生类新定义的成员变量不可无值可赋 3 私有或保护派生类的对象不能够赋值给基类的对象 : 派生类不能够突破关键词 private 或 protected 所限定的访问权限 4 可将派生类对象的地址赋给基类类型的指针变量, 例如 Base *ptr = &der_obj 5 派生类的对象可初始化基类类型的引用, 例如 Base &ref = der_obj 在使用基类类型的指针变量或引用时 : 只允许访问从相应基类中继承来的成员, 不允许访问其他基类的成员或派生类新增加的成员 请思考原因 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

100 总结与思考 作业 总结与思考 Dongke Sun (Southeast University) C++ Programming and Algorithms April 12, / 38

幻灯片 1

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

More information

エスポラージュ株式会社 住所 : 東京都江東区大島 東急ドエルアルス大島 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

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 - 第06讲_继承.ppt [兼容模式]

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

More information

第七讲 继承与多态

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

More information

C++_Lecture

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

More information

Microsoft PowerPoint - 04-Inheritance.ppt

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

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

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

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

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

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

Strings

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

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

Chapter12 Derived Classes

Chapter12   Derived Classes 继 承 -- 派 生 类 复 习 1. 有 下 面 类 的 说 明, 有 错 误 的 语 句 是 : class X { A) const int a; B) X(); C) X(int val) {a=2 D) ~X(); 答 案 :C 不 正 确, 应 改 成 X(int val) : a(2) { 2. 下 列 静 态 数 据 成 员 的 特 性 中, 错 误 的 是 A) 说 明 静 态 数

More information

Microsoft PowerPoint - CPP-Ch Print.ppt [兼容模式]

Microsoft PowerPoint - CPP-Ch Print.ppt [兼容模式] Chapter 13 Object-Oriented Programming: Polymorphism http://jssec.seu.edu.cn 杨明 yangming2002@seu.edu.cn OBJECTIVES What polymorphism( 多态 ) is, how it makes programming more convenient, and how it makes

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

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

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

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

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

untitled

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

More information

Strings

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

More information

Microsoft Word - 095_2015.09.26 什麼最快樂 (白話與經文加註)-ok .doc

Microsoft Word - 095_2015.09.26  什麼最快樂 (白話與經文加註)-ok .doc 釋 厚 觀 ( 福 嚴 推 廣 教 育 班,2015.9.26) 各 位 法 師 各 位 居 士, 大 家 好! 今 天 跟 大 家 分 享 一 則 佛 典 故 事, 這 故 事 出 自 法 句 譬 喻 經, 在 大 正 藏 第 4 冊 595 頁 中 欄 到 596 頁 上 欄 過 去, 佛 在 舍 衛 國 祇 園 精 舍 時, 有 四 位 新 學 比 丘 一 起 來 到 㮈 樹 下 坐 禪 修

More information

Microsoft PowerPoint - 07 派生数据类型

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

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

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

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

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

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

软件工程文档编制

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

More information

<4D6963726F736F667420506F776572506F696E74202D20332D322E432B2BC3E6CFF2B6D4CFF3B3CCD0F2C9E8BCC6A1AAD6D8D4D8A1A2BCCCB3D0A1A2B6E0CCACBACDBEDBBACF2E707074>

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

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

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

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

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

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

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

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

第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 PERSON 1 Person 题目描述 编写程序, 定义一个基类 Person, 包含 name 和 age 两个数据成员 ; 再由它派生出学生类 Student 和教师类 Teacher, 其中学生类添加学号 no 数据, 教师类添加职称 title 数据 ; 要求每个类均有构造函数 析构函数和显示数据的函数

More information

슬라이드 1

슬라이드 1 2018-2019 年度第二学期 00106501 计算机图形学 童伟华管理科研楼 1205 室 E-mail: tongwh@ustc.edu.cn 中国科学技术大学数学科学学院 http://math.ustc.edu.cn/ 附讲三 C/C++ 编程 ( 二 ) 2 C++ 特点 C++ 是面对对象 (object oriented) 编程语言 纯面向对象语言 : 指不管什么东西, 都应该存在于对象之中,

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++ 程序设计 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 Word - chap10.doc

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

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

CHAPTER VC#

CHAPTER VC# 1. 2. 3. 4. CHAPTER 2-1 2-2 2-3 2-4 VC# 2-5 2-6 2-7 2-8 Visual C# 2008 2-1 Visual C# 0~100 (-32768~+32767) 2 4 VC# (Overflow) 2-1 2-2 2-1 2-1.1 2-1 1 10 10!(1 10) 2-3 Visual C# 2008 10! 32767 short( )

More information

FY.DOC

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

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

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

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

More information

幻灯片 1

幻灯片 1 信息科学技术学院 程序设计实习 郭炜微博 http://weibo.com/guoweiofpku http://blog.sina.com.cn/u/3266490431 刘家瑛微博 http://weibo.com/pkuliujiaying 1 信息科学技术学院 程序设计实习 郭炜刘家瑛 虚函数和多态 (P247) 2 虚函数 在类的定义中, 前面有 virtual 关键字的成员函数就是虚函数

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++ 程序设计 实验 2 - 参考答案 MASTER 2017 年 5 月 21 日 1

C++ 程序设计 实验 2 - 参考答案 MASTER 2017 年 5 月 21 日 1 C++ 程序设计 实验 2 - 参考答案 MASTER 2017 年 5 月 21 日 1 1 CRECT 类 1 CRect 类 设计矩形类, 包含 长度和宽度信息 基本构造函数 基础属性的访问接口 ( 读 / 写, Read/Write, Get/Set) 计算周长和面积 ( 注 : 基本构造函数, 一个无参数的默认构造函数, 以及一个初始化数据成员的构造函数如果数据成员的初始化有多种形式, 就提供多个构造函数

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

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

Microsoft Word - 970617cppFinalSolution.doc

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

More information

Microsoft PowerPoint - 第07讲_多态1.ppt [兼容模式]

Microsoft PowerPoint - 第07讲_多态1.ppt [兼容模式] 程序设计实习 (I): C++ 程序设计 第七讲多态 上节内容回顾 基本概念 : 继承 基类 派生类 派生类的成员组成 可见性 派生类的构造 析构 派生类与基类的指针类型转换 2 回顾 : public 继承 class base { private: int m; public: int q; base(int ti=0):m(i){} }; class derived : public base

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

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

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

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

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

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

模板

模板 制作人 : 张刚 目录 类和对象 面向对象程序设计基本特征 类的声明 构造方法 成员变量和方法 封装 继承 多态 包 访问控制 final static 抽象类和接口 内部类 沈阳工业大学软件学院 Java 课程教研组 Page 2 核心知识点 类 对象 三个基本特征 类的基本结构 成员变量 构造方法 成员方法 类实例 对象创建和操作 沈阳工业大学软件学院 Java 课程教研组 Page 3 1.

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

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

. v dx v d () () l s dl s d (_) d () v s v s () a dv a d (_) ( ) ( ) x- = v- = = v 0 = m/s a = = m/s 2 a- = ( ) x- v- a- Page 2 of 20

. v dx v d () () l s dl s d (_) d () v s v s () a dv a d (_) ( ) ( ) x- = v- = = v 0 = m/s a = = m/s 2 a- = ( ) x- v- a- Page 2 of 20 Page 1 of 20 . v dx v d () () l s dl s d (_) d () v s v s () a dv a d (_) ( ) ( ) x- = v- = = v 0 = m/s a = = m/s 2 a- = ( ) x- v- a- Page 2 of 20 (1) x v a (2) x v a x v (3) x v a x v a x v Page 3 of

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

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

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

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

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

More information

untitled

untitled 不 料 料 例 : ( 料 ) 串 度 8 年 數 串 度 4 串 度 數 數 9- ( ) 利 數 struct { ; ; 數 struct 數 ; 9-2 數 利 數 C struct 數 ; C++ 數 ; struct 省略 9-3 例 ( 料 例 ) struct people{ char name[]; int age; char address[4]; char phone[]; int

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

没有幻灯片标题

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

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

<4D F736F F F696E74202D20B5DA39D5C220C3E6CFF2B6D4CFF3D3EFD1D4B5C4B1E0D2EB2E BBCE6C8DDC4A3CABD5D>

<4D F736F F F696E74202D20B5DA39D5C220C3E6CFF2B6D4CFF3D3EFD1D4B5C4B1E0D2EB2E BBCE6C8DDC4A3CABD5D> 第 9 章 面向对象语言的编译 本章内容 概述面向对象语言的重要概念和实现技术 以 C++ 语言为例, 介绍如何将 C++ 程序翻译 成 C 程序 实际的编译器大都把 C++ 程序直接翻译成低 级语言程序 91 9.1 面向对象语言的概念 9.1.1 对象和对象类 对象 由一组属性和操作于这组属性的过程组成 属性到值的映射称为对象的状态, 过程称为方法 对象类 一类对象的总称, 规范了该类中对象的属性和方法,

More information

2.181% 0.005%0.002%0.005% 2,160 74,180, ,000, ,500,000 1,000,000 1,000,000 1,000,000 2

2.181% 0.005%0.002%0.005% 2,160 74,180, ,000, ,500,000 1,000,000 1,000,000 1,000,000 2 90,000,000 9,000,000 81,000,000 2.18 0.10 3300 1 2.181% 0.005%0.002%0.005% 2,160 74,180,000 8.24 81,000,000 2.18 13,500,000 1,000,000 1,000,000 1,000,000 2 1,000,0001,000,000 1,000,000 2,000 2.18 1% 0.005%0.002%0.005%

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

untitled

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

More information

Generated by Unregistered Batch DOC TO PDF Converter , please register! 浙江大学 C 程序设计及实验 试题卷 学年春季学期考试时间 : 2003 年 6 月 20 日上午 8:3

Generated by Unregistered Batch DOC TO PDF Converter , please register! 浙江大学 C 程序设计及实验 试题卷 学年春季学期考试时间 : 2003 年 6 月 20 日上午 8:3 浙江大学 C 程序设计及实验 试题卷 2002-2003 学年春季学期考试时间 : 2003 年 6 月 20 日上午 8:30-10:30 注意 : 答题内容必须写在答题卷上, 写在本试题卷上无效 一. 单项选择题 ( 每题 1 分, 共 10 分 ) 1. 下列运算符中, 优先级最低的是 A.

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

北京大学

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

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

論鄭玄對《禮記‧月令》的考辨

論鄭玄對《禮記‧月令》的考辨 19997 183-196 論 鄭 玄 對 禮 記 月 令 的 考 辨 183 論 鄭 玄 對 禮 記 月 令 的 考 辨 一 問 題 的 背 景 20b 8a 1 472 24 20a 33 7a 2 3 1 35 60 64 472 240241 2 1a 3 19b 184 4 5 二 鄭 玄 考 辨 月 令 成 書 時 代 及 來 源 的 論 證 65 4 20b 282 5 235244

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

Guava学习之CharSequenceReader

Guava学习之CharSequenceReader CharSequenceReader 类是以 CharSequence 的形式读取字符 CharSequenceReader 类继承自 Reader 类, 除了 remaining() hasremaining() 以及 checkopen() 函数之后, 其他的函数都是重写 Reader 类中的函数 CharSequenceReader 类声明没有用 public 关键字, 所以我们暂时还不能调用这个类

More information

Microsoft PowerPoint - ch12 [Compatibility Mode]

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

More information

Microsoft Word - 物件導向編程精要.doc

Microsoft Word - 物件導向編程精要.doc Essential Object-Oriented Programming Josh Ko 2007.03.11 object-oriented programming C++ Java OO class object OOP Ruby duck typing complexity abstraction paradigm objects objects model object-oriented

More information

Microsoft PowerPoint - 7. 面向对象程序设计-Object-Oriented Programming.ppt [兼容模式]

Microsoft PowerPoint - 7. 面向对象程序设计-Object-Oriented Programming.ppt [兼容模式] 面向对象程序设计 Object-Oriented Programming(OOP) Classes,Inheritance, Polymorphism A Survey of Programming Techniques Unstructured programming, procedural programming, modular programming and object-oriented

More information

Microsoft PowerPoint - 08_OO_CJC.ppt

Microsoft PowerPoint - 08_OO_CJC.ppt C++ 中的 Hello World! C 程序设计语言 第 8 章 OO 与 C++ Java C# 孙志岗 sun@hit.edu.cn http://sunner.cn 兼容 C 语言的 : #include int main() printf("hello,, world!\n"); return 0; 更具 C++ 味道的 : #include int

More information

C C C The Most Beautiful Language and Most Dangerous Language in the Programming World! C 2 C C C 4 C 40 30 10 Project 30 C Project 3 60 Project 40

C C C The Most Beautiful Language and Most Dangerous Language in the Programming World! C 2 C C C 4 C 40 30 10 Project 30 C Project 3 60 Project 40 C C trio@seu.edu.cn C C C C The Most Beautiful Language and Most Dangerous Language in the Programming World! C 2 C C C 4 C 40 30 10 Project 30 C Project 3 60 Project 40 Week3 C Week5 Week5 Memory & Pointer

More information

IO

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

More information

Microsoft PowerPoint - C语言课件-9-结构体.pptx

Microsoft PowerPoint - C语言课件-9-结构体.pptx 第九章结构体 郎大鹏 第九章结构体 9.1 结构体类型的声明方法 9.2 结构体类型变量的定义与使用 9.3 结构体数组 9.4 编程举例 9.5 习题 9.1 结构体类型的声明方法 结构体声明的语法形式如下 : struct 结构体标识符 成员变量列表 ; }; 例如, 为了描述班级 ( 假设仅仅包括班级编号 专业 人数等信息 ), 可以声明如下的结构体类型 struct Class char Code[10];

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# C# C C# C# C# C# C# microservices C# More Effective C# More Effective C# C# C# C# Effective C# 50 C# C# 7 Effective vii

前言 C# C# C# C C# C# C# C# C# microservices C# More Effective C# More Effective C# C# C# C# Effective C# 50 C# C# 7 Effective vii 前言 C# C# C# C C# C# C# C# C# microservices C# More Effective C# More Effective C# C# C# C# Effective C# 50 C# C# 7 Effective vii C# 7 More Effective C# C# C# C# C# C# Common Language Runtime CLR just-in-time

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

Microsoft Word - CPE考生使用手冊160524.docx

Microsoft Word - CPE考生使用手冊160524.docx 大 學 程 式 能 力 檢 定 (CPE) 考 生 使 用 手 冊 2016 年 5 月 24 日 這 份 手 冊 提 供 給 參 加 CPE 檢 定 考 試 的 考 生 內 容 包 含 考 試 環 境 的 使 用, 以 及 解 題 時 所 使 用 I/O 的 基 本 知 識 1. 如 欲 報 名 參 加 CPE 考 試, 請 先 於 CPE 網 站 完 成 帳 號 註 冊, 然 後 再 報 名 該

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

Microsoft Word - 第7章 类与对象.docx

Microsoft Word - 第7章 类与对象.docx 第 7 章类与对象 案例 1 地址类 #include class Address char Name[21]; char Street[51]; char City[51]; char Postcode[10]; SetAddress(char *name,char *street,char *city,char *postcode); void ChangeName(char

More information

试卷代号 ~1075 座位号 E 口 国家开放大学 ( 中央广播电视大学 )20]5 年秋季学期 " 开放本科 " 期末考试 C 十十语言程序设计 试题 同二二十斗 2016 年 1 月 巴叫一 1. 下面的保留字 ( ) 不能作为函数的返回类型 A. void B. int C. new D. l

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

More information