类中说明的重载

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 在类中说明的重载
  5. * */
  6. class Cube {
  7. public:
  8. Cube() {
  9. height = 1;
  10. width = 2;
  11. length = 3;
  12. }
  13. Cube(int h, int w, int l) {
  14. height = h;
  15. width = w;
  16. length = l;
  17. }
  18. private:
  19. int height;
  20. int width;
  21. int length;
  22. };
  23. int main() {
  24. Cube c1;
  25. Cube c1(4, 5, 6);
  26. return 0;
  27. }

基类成员在派生类的重载

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 基类成员在派生类的重载
  5. * */
  6. class Point {
  7. public:
  8. Point(int x, int y) {
  9. Point::x = x;
  10. Point::y = y;
  11. }
  12. float area() {
  13. return 0.0;
  14. }
  15. private:
  16. int x;
  17. int y;
  18. };
  19. class Circle: public Point {
  20. public:
  21. Circle(int x, int y, int r): Point(x, y) {
  22. Circle::radius = r;
  23. }
  24. float area() {
  25. return 3.1415926535*radius*radius;
  26. }
  27. private:
  28. int radius;
  29. };
  30. int main() {
  31. Point p(10, 10);
  32. Circle c(5, 5, 20);
  33. cout<<"point1:"<<p.area()<<endl;
  34. cout<<"circle1:"<<c.area()<<endl;
  35. cout<<"point1:"<<c.Point::area()<<endl; // 可以通过作用域符号找到基类的同名函数
  36. return 0;
  37. }

虚函数

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 虚函数的作用
  5. * */
  6. class Undergra {
  7. public:
  8. virtual void cal_fee() {
  9. fee1 = 4200;
  10. fee2 = 800;
  11. fee3 = 400;
  12. fee = fee1 + fee2 + fee3;
  13. }
  14. virtual void dis() {
  15. cout<<"undergraduate fee:"<<endl;
  16. cout<<"study fee:"<<fee1<<endl;
  17. cout<<"sleep fee:"<<fee2<<endl;
  18. cout<<"other fee:"<<fee3<<endl;
  19. cout<<"total fee:"<<fee<<endl;
  20. }
  21. protected:
  22. int fee1;
  23. int fee2;
  24. int fee3;
  25. int fee;
  26. };
  27. class PostGra: public Undergra {
  28. public:
  29. void cal_fee() {
  30. fee1 = 1800;
  31. fee2 = 400;
  32. fee = fee1 + fee2;
  33. }
  34. void dis() {
  35. cout<<"postgraduate fee:"<<endl;
  36. cout<<"sleep fee:"<<fee1<<endl;
  37. cout<<"other fee:"<<fee2<<endl;
  38. cout<<"total fee:"<<fee<<endl;
  39. }
  40. };
  41. int main() {
  42. Undergra u1;
  43. PostGra p1;
  44. Undergra *ptr = &u1;
  45. ptr->cal_fee();
  46. ptr->dis();
  47. ptr = &p1;
  48. ptr->cal_fee();
  49. ptr->dis();
  50. return 0;
  51. }

虚函数是其他类的派生类,不会影响基类的同名函数

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 虚函数
  5. * 如果基类成员函数是虚函数,那么所有派生类都是虚函数
  6. * 如果虚函数是其他类的派生类,那么基类的同名函数保持原有性质
  7. * */
  8. class A {
  9. public:
  10. void f(int i) {
  11. cout<<"A"<<endl;
  12. }
  13. };
  14. class B: public A {
  15. public:
  16. virtual void f(int i) {
  17. cout<<"B"<<endl;
  18. }
  19. };
  20. class C: public B {
  21. public:
  22. void f(int i) {
  23. cout<<"C"<<endl;
  24. }
  25. };
  26. class D: public C {
  27. public:
  28. void f(int ) {
  29. cout<<"D"<<endl;
  30. }
  31. };
  32. int main() {
  33. A *pa, a;
  34. B *pb, b;
  35. C c;
  36. D d;
  37. pa = &a; pa->f(1);
  38. pa = &b; pa->f(1);
  39. pa = &c; pa->f(1);
  40. pa = &d; pa->f(1);
  41. // 由于 A 的 f 不是虚函数,那么其子类都会调用 A 的f函数
  42. // B 的f是虚函数,那么其子类的f 都具有虚函数的性质
  43. pb = &b; pb->f(1);
  44. pb = &c; pb->f(1);
  45. pb = &d; pb->f(1);
  46. return 0;
  47. }

只有通过基类指针和引用才能实现虚函数特性

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 只有通过基类指针和引用才能实现虚函数特性
  5. * */
  6. class B {
  7. public:
  8. virtual void f() {
  9. cout<<"B f"<<endl;
  10. }
  11. };
  12. class D: public B {
  13. public:
  14. void f() {
  15. cout<<"D f"<<endl;
  16. }
  17. };
  18. int main() {
  19. D d;
  20. B *pb = &d, &rb = d, b;
  21. b = d; // 截断赋值,因此实质还是调用B的函数
  22. b.f();
  23. pb->f(); // 虚函数特性
  24. rb.f(); // 虚函数特性
  25. return 0;
  26. }

派生类从基类继承的成员函数访问虚函数时,会访问派生类的版本

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 派生类从基类继承的成员函数访问虚函数时,会访问派生类的版本
  5. * */
  6. class B {
  7. public:
  8. void f() {
  9. g();
  10. }
  11. virtual void g() {
  12. cout<<"B g"<<endl;
  13. }
  14. };
  15. class D: public B {
  16. public :
  17. void g() {
  18. cout<<"D g"<<endl;
  19. }
  20. };
  21. int main() {
  22. D d;
  23. d.f(); // 这里访问的是派生类中的g,如果 virtual 关键字去掉,那么访问基类中的g
  24. return 0;
  25. }

虚函数调用过程

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 虚函数调用过程
  5. * */
  6. class B {
  7. public:
  8. void f() {
  9. cout<<"B f"<<endl;
  10. }
  11. virtual void vf() {
  12. cout<<"B vf"<<endl;
  13. }
  14. void ff() {
  15. vf();
  16. f();
  17. }
  18. virtual void vff() {
  19. vf();
  20. f();
  21. }
  22. };
  23. class D: public B {
  24. public:
  25. void f() {
  26. cout<<"D f"<<endl;
  27. }
  28. void ff() {
  29. f();
  30. vf();
  31. }
  32. void vf() {
  33. cout<<"D vf"<<endl;
  34. }
  35. };
  36. int main() {
  37. D d;
  38. B *pb = &d;
  39. pb->f(); // 非虚函数,调用 B 的f
  40. pb->ff(); // 非虚函数,调用 B 的ff,从而调用 D的vf 以及B 的f
  41. pb->vf(); // 虚函数,调用 D 的vf
  42. pb->vff(); // 虚函数,调用 D 的vf 以及 B 的f
  43. return 0;
  44. }

虚析构函数

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 虚析构函数
  5. * */
  6. class A {
  7. public :
  8. virtual ~A() {
  9. cout<<"destruct A"<<endl;
  10. }
  11. };
  12. class B: public A {
  13. public:
  14. ~B() {
  15. cout<<"destruct B"<<endl;
  16. }
  17. };
  18. int main() {
  19. A *p = new B();
  20. delete p;
  21. return 0;
  22. }

输出

  1. destruct B
  2. destruct A

如果没有 virtual ,那么只会调用 A 的析构函数

纯虚函数

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 纯虚函数
  5. * */
  6. class Point {
  7. public:
  8. Point(int i = 0, int j = 0) {
  9. x0 = i;
  10. y0 = j;
  11. }
  12. virtual void Draw() = 0;
  13. private:
  14. int x0, y0;
  15. };
  16. class Line: public Point {
  17. public:
  18. Line(int i = 0, int j = 0, int m = 0, int n = 0): Point(i, j) {
  19. x1 = m;
  20. y1 = n;
  21. }
  22. void Draw() {
  23. cout<<"draw line"<<endl;
  24. }
  25. private:
  26. int x1, y1;
  27. };
  28. class Ellipse: public Point {
  29. public:
  30. Ellipse(int i = 0, int j = 0, int p = 0, int q = 0): Point(i, j) {
  31. x2 = p;
  32. y2 = q;
  33. }
  34. void Draw() {
  35. cout<<"draw ellipse"<<endl;
  36. }
  37. private:
  38. int x2, y2;
  39. };
  40. int main() {
  41. Line *line = new Line;
  42. Ellipse *ellipse = new Ellipse;
  43. line->Draw();
  44. ellipse->Draw();
  45. delete line, ellipse;
  46. return 0;
  47. }

抽象类

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 抽象类
  5. * */
  6. class Figure {
  7. public:
  8. virtual float area()=0;
  9. };
  10. class Circle: public Figure {
  11. public:
  12. Circle(float r) {
  13. radius = r;
  14. }
  15. float area() {
  16. return radius * radius * 3.1415926535;
  17. }
  18. private:
  19. float radius;
  20. };
  21. class Triangle: public Figure {
  22. public:
  23. Triangle(float h, float w) {
  24. high = h;
  25. width = w;
  26. }
  27. float area() {
  28. return high * width * 0.5;
  29. }
  30. protected:
  31. float high, width;
  32. };
  33. class Rectangle: public Triangle {
  34. public:
  35. Rectangle(float h, float w):Triangle(h, w) {
  36. }
  37. float area() {
  38. return high * width;
  39. }
  40. };
  41. int main() {
  42. Figure *p[6];
  43. p[0] = new Triangle(3.0, 2.0);
  44. p[1] = new Rectangle(2.5, 3.0);
  45. p[2] = new Rectangle(5.0, 1.0);
  46. p[3] = new Rectangle(3.0, 6.0);
  47. p[4] = new Circle(5.2);
  48. p[5] = new Circle(8.0);
  49. for(int i = 0; i < 6; i++) {
  50. printf("area[%d] = %f\n", i, p[i]->area());
  51. }
  52. return 0;
  53. }

抽象类不能建立对象

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 抽象类不能建立对象
  5. * 函数原型不一样,仍然是抽象类
  6. * */
  7. class Figure {
  8. protected:
  9. double x, y;
  10. public:
  11. void set(double i, double j) {
  12. x = i;
  13. y = j;
  14. }
  15. virtual void area() = 0;
  16. };
  17. class Triangle : public Figure {
  18. public:
  19. void area() {
  20. printf("triangle area : %f\n", x*y*0.5);
  21. }
  22. };
  23. class Rectangle : public Figure {
  24. public:
  25. void area(int i) { // 只有函数原型一模一样才是虚函数,否则是重载,因此 Rectangle 仍然是抽象类
  26. printf("rectangle area : %f\n", x*y);
  27. }
  28. };
  29. int main() {
  30. Figure *pf;
  31. // Figure f; // 错误,抽象类不能建立对象
  32. // Rectangle r; // 错误,area 是重载而不是虚函数,因此仍然是抽象类
  33. Triangle t;
  34. t.set(10, 20);
  35. pf = &t;
  36. pf->area();
  37. Figure &rf = t;
  38. rf.set(20, 20);
  39. rf.area();
  40. return 0;
  41. }