多继承的构造函数顺序

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 多继承构造函数
  5. * */
  6. class B1 {
  7. public:
  8. B1(int i) {
  9. cout<<"construct B1"<<endl;
  10. }
  11. };
  12. class B2 {
  13. public :
  14. B2(int j) {
  15. cout<<"construct B2"<<endl;
  16. }
  17. };
  18. class B3 {
  19. public:
  20. B3() {
  21. cout<<"construct B3"<<endl;
  22. }
  23. };
  24. class C: public B2, public B1, public B3 { // 基类构造函数按照这个顺序
  25. public:
  26. C(int a, int b, int c, int d): B1(a), b2(d), b1(c), B2(b) { // 注意这个顺序无关
  27. }
  28. private: // 子对象构造函数顺序
  29. B1 b1;
  30. B2 b2;
  31. B3 b3;
  32. };
  33. int main() {
  34. C obj(1, 2, 3, 4);
  35. return 0;
  36. }

输出

  1. construct B2
  2. construct B1
  3. construct B3
  4. construct B1
  5. construct B2
  6. construct B3

多继承的析构函数顺序

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 多继承析构函数的顺序
  5. * */
  6. class B1 {
  7. public :
  8. B1(int x) {
  9. cout<<"construct B1"<<endl;
  10. }
  11. ~B1() {
  12. cout<<"destruct B1"<<endl;
  13. }
  14. };
  15. class B2 {
  16. public:
  17. B2() {
  18. cout<<"construct B2"<<endl;
  19. }
  20. ~B2() {
  21. cout<<"destruct B2"<<endl;
  22. }
  23. };
  24. class A: public B1, public B2 {
  25. public:
  26. A(int a, int b): B1(a), B2(), b1(b), b2() {
  27. cout<<"construct A"<<endl;
  28. }
  29. ~A() {
  30. cout<<"destruct A"<<endl;
  31. }
  32. private:
  33. B1 b1;
  34. B2 b2;
  35. };
  36. int main() {
  37. A a(10, 20);
  38. return 0;
  39. }

输出

  1. construct B1
  2. construct B2
  3. construct B1
  4. construct B2
  5. construct A
  6. destruct A
  7. destruct B2
  8. destruct B1
  9. destruct B2
  10. destruct B1

多继承时不同基类同名成员的二义性

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 多继承中不同基类成员的二义性
  5. * */
  6. class A {
  7. public:
  8. void set_a(int a) {
  9. this->a = a;
  10. }
  11. int get(){
  12. return this->a;
  13. }
  14. private:
  15. int a;
  16. };
  17. class B {
  18. public:
  19. void set_b(int b) {
  20. this->b = b;
  21. }
  22. int get() {
  23. return this->b;
  24. }
  25. private:
  26. int b;
  27. };
  28. class C: public A, public B {
  29. public:
  30. void set_c(int c) {
  31. this->c = c;
  32. }
  33. private:
  34. int c;
  35. };
  36. int main() {
  37. C c;
  38. // c.get(); // 错误,引起了二义性,不清楚调用哪个类的get()函数
  39. // 方法一,通过作用域分辨
  40. c.A::get();
  41. c.B::get();
  42. return 0;
  43. }
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 多继承中不同基类成员的二义性
  5. * */
  6. class A {
  7. public:
  8. void set_a(int a) {
  9. this->a = a;
  10. }
  11. int get(){
  12. return this->a;
  13. }
  14. private:
  15. int a;
  16. };
  17. class B {
  18. public:
  19. void set_b(int b) {
  20. this->b = b;
  21. }
  22. int get() {
  23. return this->b;
  24. }
  25. private:
  26. int b;
  27. };
  28. class C: public A, public B {
  29. public:
  30. void set_c(int c) {
  31. this->c = c;
  32. }
  33. int get() {
  34. cout<<c<<endl;
  35. return this->c;
  36. }
  37. private:
  38. int c;
  39. };
  40. int main() {
  41. C c;
  42. // c.get(); // 错误,引起了二义性,不清楚调用哪个类的get()函数
  43. // 方法一,通过作用域分辨
  44. // c.A::get();
  45. // c.B::get();
  46. // 方法二,覆写重名函数
  47. c.set_c(1);
  48. c.get();
  49. return 0;
  50. }

访问共同基类成员的二义性

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 访问共同基类成员的二义性
  5. * */
  6. class A {
  7. public:
  8. void dis(){
  9. }
  10. };
  11. class B1: public A {
  12. public:
  13. void disB1() {
  14. }
  15. };
  16. class B2: public A {
  17. public:
  18. void disB2() {
  19. }
  20. };
  21. class C: public B1, public B2 {
  22. public:
  23. void disC() {
  24. }
  25. };
  26. int main() {
  27. C c;
  28. // c.dis(); // 错误,C 中包含C1和C2中的dis()函数,因此产生二义性
  29. //c.A::dis() 依然会出现二义性,因为实质上 c 包含了二份
  30. // 下面这两个是可以的,没有二义性
  31. c.B1::dis();
  32. c.B2::dis();
  33. return 0;
  34. }

虚基类概念:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 虚基类概念
  5. * */
  6. class A {
  7. public:
  8. void dis() {
  9. cout<<"A: a="<<a<<endl;
  10. }
  11. int a;
  12. };
  13. class B1: virtual public A {
  14. };
  15. class B2: virtual public A {
  16. };
  17. class C: public B1, public B2 {
  18. };
  19. int main() {
  20. C c;
  21. c.a = 9;
  22. c.dis();
  23. return 0;
  24. }

虚基类的初始化

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 虚基类的初始化
  5. * */
  6. class A {
  7. public:
  8. A(int i) {
  9. a = i;
  10. cout<<"construct A"<<endl;
  11. }
  12. void dis() {
  13. cout<<"A: a="<<a<<endl;
  14. }
  15. int a;
  16. };
  17. class B1: virtual public A {
  18. public:
  19. B1(int j): A(j) {
  20. cout<<"construct B1"<<endl;
  21. }
  22. int b1;
  23. };
  24. class B2: virtual public A {
  25. public:
  26. B2(int j): A(j) {
  27. cout<<"construct B2"<<endl;
  28. }
  29. int b2;
  30. };
  31. class C: public B1, public B2 {
  32. public:
  33. C(int j): A(j), B1(j), B2(j) { // 虽然 B1和B2中都有 A 的构造函数,但是C 是A的最远派生类,只会通过最远派生类的构造函数对虚基类初始化
  34. cout<<"construct C"<<endl;
  35. }
  36. int c;
  37. };
  38. int main() {
  39. C c(3);
  40. c.a = 9;
  41. c.dis();
  42. return 0;
  43. }

虚基类构造函数的执行顺序

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 虚基类的构造函数执行顺序
  5. * */
  6. class A{
  7. int a;
  8. public:
  9. A(){
  10. printf("construct A\n");
  11. }
  12. };
  13. class B {
  14. public:
  15. B() {
  16. printf("construct B\n");
  17. }
  18. };
  19. class B1: virtual public B, virtual public A {
  20. public:
  21. B1(int i) {
  22. printf("construct b1\n");
  23. }
  24. };
  25. class B2: public A, virtual public B {
  26. public:
  27. B2(int j) {
  28. printf("construct b2\n");
  29. }
  30. };
  31. // 虚基类并非基类派生,那么先调用虚基类的基类构造函数,再调用虚基类的构造函数
  32. // 也就是先调用 B1 和 B2 的构造函数,其中 B1 调用 B 再调用 A,而B2已经调用过B了,因此只调用A的(虚基类的构造函数已经被调用过了,那么不会再调用)
  33. // 由于 B2 不是虚继承 A,因此会再调用A,而不会调用 B
  34. class D: public B1, public B2 {
  35. public:
  36. D(int m, int n):B1(m), B2(n) {
  37. printf("construct D\n");
  38. }
  39. A a;
  40. };
  41. int main() {
  42. D d(1, 2);
  43. return 0;
  44. }

虚基类由最终派生类初始化

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /**
  4. * 虚基类由最终派生类初始化
  5. * */
  6. class A {
  7. int a;
  8. public:
  9. A(int x) {
  10. a = x;
  11. printf("virtual base a\n");
  12. }
  13. };
  14. class B: virtual public A {
  15. public:
  16. B(int i): A(i) {
  17. printf("virtual base b\n");
  18. }
  19. };
  20. class C: virtual public A {
  21. int x;
  22. public:
  23. C(int i):A(i) {
  24. printf("construct C\n");
  25. x = i;
  26. }
  27. };
  28. class ABC: public C, public B {
  29. public:
  30. ABC(int i, int j, int k): C(i), B(j), A(i) { // 由于 A 是虚基类,所以必须在这里进行初始化
  31. printf("construct ABC\n");
  32. }
  33. };
  34. int main() {
  35. ABC abc(1, 2, 3);
  36. return 0;
  37. }