c++之——派生类的同名成员和函数调用方式及构造析构顺序
1 #include<iostream>
2 using namespace std;
3 class Object {
4 public:
5 Object(int test) :a(1), b(2), c(3) { cout << "object 构造\n"; }
6 ~Object()
7 {
8 cout << "object 析构\n";
9 }
10 int a;
11 int b;
12 int c;
13 void same_fuc()
14 {
15 cout << "object test...\n";
16 }
17 void o_print()
18 {
19 cout << "a b c is" << a << " " << b << " " << c << endl;
20 }
21
22 };
23 class Parent :public Object {
24 public:
25 Parent(int test):Object(1), a(100),b(200),c(300),obj1(1),obj2(2)//NOTE
26 {
27 cout << "parent 构造。。。\n";
28 }
29 ~Parent()
30 {
31 cout << "Parent 析构。。。\n";
32 }
33 int a;
34 int b;
35 int c;
36 void same_fuc()
37 {
38 cout << "Parent test...\n";
39 }
40 void p_print()
41 {
42 cout << "a b c is" << a << " " << b << " " << c << endl;
43 }
44 Object obj1;
45 Object obj2;
46 };
47 class Child :public Parent
48 {
49 public:
50 Child() :Parent(1), a(1000), b(2000), c(3000) { cout << "child 构造\n"; }
51 ~Child()
52 {
53 cout << "child 析构,,,\n";
54 }
55 void c_print()
56 {
57 cout << "a b c is" << a << " " << b << " " << c << endl;
58 }
59 void same_fuc()
60 {
61 cout << "child test...\n";
62 }
63 int a;
64 int b;
65 int c;
66 };
67
68 int main()
69 {
70
71 Child c1;
72 c1.c_print();
73 c1.a = 520;//默认等价于c1.Child::a=520;
74 c1.c_print();
75 c1.Parent::a = 5200;
76 c1.p_print();
77 c1.c_print();
78 c1.Object::a = 52000;
79 c1.o_print();
80 c1.c_print();
81
82 c1.same_fuc();//默认等价于c1.Child::same_fuc();
83 c1.Parent::same_fuc();
84 c1.Object::same_fuc();
85 return 0;
86 }
上诉代码,如果直接使用子类对象调用子类的某个和父类同名函数或者使用同名变量,默认使用子类的,但我们可以加上域作用符强制使用父类的属性或者方法。
同名函数再探:
1 #include<iostream>
2 using namespace std;
3
4 class Parent {
5 public:
6 Parent(int test):a(100),b(200),c(300)
7 {
8 cout << "parent 构造。。。\n";
9 }
10 ~Parent()
11 {
12 cout << "Parent 析构。。。\n";
13 }
14 int a;
15 int b;
16 int c;
17 virtual void same_fuc()//不加virtual就不会产生多态
18 {
19 cout << "Parent test...\n";
20 }
21 void p_print()
22 {
23 cout << "a b c is" << a << " " << b << " " << c << endl;
24 }
25
26 };
27 class Child :public Parent
28 {
29 public:
30 Child() :Parent(1), a(1000), b(2000), c(3000) { cout << "child 构造\n"; }
31 ~Child()
32 {
33 cout << "child 析构,,,\n";
34 }
35 void c_print()
36 {
37 cout << "a b c is" << a << " " << b << " " << c << endl;
38 }
39 void same_fuc()
40 {
41 cout << "child test...\n";
42 }
43 int a;
44 int b;
45 int c;
46 };
47 void test(Parent &p)
48 {
49 p.same_fuc();
50 }
51 int main()
52 {
53
54 Child c1;
55 test(c1);
56 Parent p1(1);
57 test(p1);
58 return 0;
59 }
当且仅当对通过引用或者指针调用虚函数时,才会在运行时解析该调用,也只有在这种情况下对象的动态类型才有可能与静态类型不同。
一旦某个函数被声明成虚函数,则在所有派生类中它都是虚函数。
一个派生类的函数如果覆盖了某个继承而来的虚函数,那么它的参数类型必须与被它覆盖的基类函数完全一致。同样,返回类型也必须与基类匹配,该返回类型规则存在一个例外,当类的虚函数返回类型是类本身的指针或者引用时,该返回类型匹配一致规则无效。eg:如果B类由A类派生得到,则基类A的虚函数可以返回A*或者A&而派生类B对应的虚函数可以返回B*或者B&,但是这样的返回类型要求从B到A的类型是可以访问的。
欢迎加入作者的小圈子
扫描下方左边二维码加入QQ交流群,扫描下方右边二维码关注个人微信公众号并获取更多隐藏干货,QQ交流群:816747642 微信公众号:Crystal软件学堂
作者:Crystal软件学堂 bilibili视频教程地址:https://space.bilibili.com/5782182 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在转载文章页面给出原文连接。 如果你觉得文章对你有所帮助,烦请点个推荐,你的支持是我更文的动力。 文中若有错误,请您务必指出,感谢给予我建议并让我提高的你。 |