1,父子间的冲突是由继承带来的,两个类之间存在了继承的关系,必然的会带来一 些问题,本文要讨论的是父子之间成员变量或成员函数的命名问题;

2,思考:

1,子类中是否可以定义父类中的同名成员?

1,可以,本文先编程解决这个问题;

2,这个问题就是同名覆盖问题;

2,如果可以,如何区分?如果不可以,为什么?

3,同名成员变量编程实验:

  1. #include <iostream>
  2. #include <string>
  3.  
  4. using namespace std;
  5.  
  6. class Parent
  7. {
  8. public:
  9. int mi;
  10. };
  11.  
  12. class Child : public Parent
  13. {
  14. public:
  15. int mi; // 编译结果通过,子类可以定义父类里面的同名变量;
  16. };
  17.  
  18. int main()
  19. {
  20. Child c;
  21.  
  22. c.mi = ; // mi 究竟是子类自定义的,还是从父类继承得到的?
  23.  
  24. return ;
  25. }

4,父子间的冲突(同名覆盖):

1,子类可以定义父类中的同名成员;

2,子类中的成员将隐藏父类中的同名成员;

1,编译器认为已经从父类中继承得到这个成员了,又自定义了一个同名成员,目的只有一个,就是你想要自己自定义的同名成员、而不想要从父类那里继承得到的同名成员,因此会产生同名覆盖现象;

3,父类中的同名成员依然存在于子类中;

1,隐藏、不是销毁;

4,通过作用域分辨符(::)访问父类中的同名成员;

5,访问父类中的同名成员方式:

1,Child c;

2,c.mi = 100;  // 子类中的 mi;

3,c.Parent::mi = 1000;  // 父类中的 mi;

6,同名成员变量深度分析编程实验:

  1. #include <iostream>
  2. #include <string>
  3.  
  4. using namespace std;
  5.  
  6. namespace A
  7. {
  8. int g_i = ;
  9. }
  10.  
  11. namespace B
  12. {
  13. int g_i = ; // 同名的全局变量,但是位于两个不同的命名空间;
  14. }
  15.  
  16. class Parent
  17. {
  18. public:
  19. int mi;
  20.  
  21. Parent()
  22. {
  23. cout << "Parent() : " << "&mi = " << &mi << endl;
  24. }
  25. };
  26.  
  27. class Child : public Parent
  28. {
  29. public:
  30. int mi; // 编译器没有简单的对同名成员报错,是因为作用域,虽然两个成员的名字相同,但是出于不同的作用域当中;同命名空间的本质是一样的;
  31.  
  32. Child()
  33. {
  34. cout << "Child() : " << "&mi = " << &mi << endl;
  35. }
  36. };
  37.  
  38. int main()
  39. {
  40. Child c; // Parent() : &mi = 0xbfb43a08 Child() : &mi = 0xbfb43a0c
  41.  
  42. c.mi = ;
  43.  
  44. c.Parent::mi = ;
  45.  
  46. cout << "&c.mi = " << &c.mi << endl; // &c.mi = 0xbfb43a0c,证明直接访问的是子类的 mi;
  47. cout << "c.mi = " << c.mi << endl; // c.mi = 100;
  48.  
  49. cout << "&c.Parent::mi = " << &c.Parent::mi << endl; // &c.Parent::mi = 0xbfb43a08; 作用域分辨符访问父类 mi;
  50. cout << "c.Parent::mi = " << c.Parent::mi << endl; // c.Parent::mi = 1000;
  51.  
  52. return ;
  53. }

1,父类和子类可以产生同名覆盖冲突,但是通过作用域分辨符可以解决这个问     题;

7,再论重载:

1,类中的成员函数可以进行重载:

1,重载函数的本质为多个不同的函数;

2,函数名和参数列表是唯一的标识;

3,函数重载必须发生在同一个作用域中;

8,问题:

1,子类中定义的函数是否能重载父类中的同名函数?

1,将父子间的冲突问题上升到成员函数了;

9,父子间的函数重载编程实验:

1,继承父类成员函数,累加父类的同名成员;

  1. #include <iostream>
  2. #include <string>
  3.  
  4. using namespace std;
  5.  
  6. class Parent
  7. {
  8. public:
  9. int mi;
  10.  
  11. void add(int v)
  12. {
  13. mi += v;
  14. }
  15.  
  16. void add(int a, int b)
  17. {
  18. mi += (a + b);
  19. }
  20. };
  21.  
  22. class Child : public Parent
  23. {
  24. public:
  25. int mi;
  26. };
  27.  
  28. int main()
  29. {
  30. Child c;
  31.  
  32. c.mi = ;
  33.  
  34. c.Parent::mi = ;
  35.  
  36. cout << "c.mi = " << c.mi << endl; // c.mi = 100;
  37.  
  38. cout << "c.Parent::mi = " << c.Parent::mi << endl; // c.Parent::mi = 1000;
  39.  
  40. c.add(); // 继承自父类的成员函数;这个函数得到的 mi 不知道后面还要定义一个子类,它知道的 mi 只是父类中的,这个时候 mi 的作用域在父类中,所以给了父类中的 mi 做累加;
  41. c.add(, ); // 继承自父类的成员函数;
  42.  
  43. cout << "c.mi = " << c.mi << endl; // c.mi = 100;
  44.  
  45. cout << "c.Parent::mi = " << c.Parent::mi << endl; // c.Parent::mi = 1006;累加到父类中的 mi 了;
  46.  
  47. return ;
  48. }

2,函数的同名覆盖:

  1. #include <iostream>
  2. #include <string>
  3.  
  4. using namespace std;
  5.  
  6. class Parent
  7. {
  8. public:
  9. int mi;
  10.  
  11. void add(int v)
  12. {
  13. mi += v;
  14. }
  15.  
  16. void add(int a, int b)
  17. {
  18. mi += (a + b);
  19. }
  20. };
  21.  
  22. class Child : public Parent
  23. {
  24. public:
  25. int mi;
  26.  
  27. void add(int x, int y, int z)
  28. {
  29. mi += (x + y + z);
  30. }
  31. };
  32.  
  33. int main()
  34. {
  35. Child c;
  36.  
  37. c.mi = ;
  38.  
  39. c.Parent::mi = ;
  40.  
  41. cout << "c.mi = " << c.mi << endl; // c.mi = 100;
  42.  
  43. cout << "c.Parent::mi = " << c.Parent::mi << endl; // c.Parent::mi = 1000;
  44.  
  45. // c.add(1); // 编译器显示没有匹配的函数调用 Child::add(int);同名成员函数覆盖,并没有重载,作用域不同;
  46. // c.add(2, 3); // 编译器显示没有匹配的函数调用 Child::add(int, int);同名成员函数覆盖,并没有重载,作用域不同;
  47.  
  48. c.Parent::add(); // 作用域分辨符解决同名成员函数覆盖问题;
  49. c.Parent::add(, ); // 作用域分辨符解决同名成员函数覆盖问题;累加父类中的 mi
  50.  
  51. c.add(, , ); // 调用子类中的 add(),默认情况下访问的就是子类中的 mi,这个地方发生了同名覆盖;
  52.  
  53. cout << "c.mi = " << c.mi << endl; // c.mi = 115;默认访问的 mi 是子类中的 mi;
  54.  
  55. cout << "c.Parent::mi = " << c.Parent::mi << endl; // c.Parent::mi = 1006;前两次累加的是父类中的 mi;
  56.  
  57. return ;
  58. }

10,父子间的冲突:

1,子类中的函数将隐藏父类的同名函数;

2,子类无法重载父类中的成员函数;

1,因为它们处于不同的作用域;

3,使用作用域分辨符访问父类中的同名函数;

1,类名加上作用域分辨符;

4,子类可以定义父类中完全相同的成员函数;

  1. #include <iostream>
  2. #include <string>
  3.  
  4. using namespace std;
  5.  
  6. class Parent
  7. {
  8. public:
  9. int mi;
  10.  
  11. void add(int v)
  12. {
  13. mi += v;
  14. }
  15.  
  16. void add(int a, int b)
  17. {
  18. mi += (a + b);
  19. }
  20. };
  21.  
  22. class Child : public Parent
  23. {
  24. public:
  25. int mi;
  26.  
  27. void add(int v) // 同名覆盖;函数重写;
  28. {
  29. mi += v;
  30. }
  31.  
  32. void add(int a, int b) // 同名覆盖;函数重写;
  33. {
  34. mi += (a + b);
  35. }
  36.  
  37. void add(int x, int y, int z) // 重载;
  38. {
  39. mi += (x + y + z);
  40. }
  41. };
  42.  
  43. int main()
  44. {
  45. Child c;
  46.  
  47. c.mi = ;
  48.  
  49. c.Parent::mi = ;
  50.  
  51. cout << "c.mi = " << c.mi << endl; // c.mi = 100;
  52.  
  53. cout << "c.Parent::mi = " << c.Parent::mi << endl; // c.Parent::mi = 1000;
  54.  
  55. c.add(); // 同名覆盖;
  56. c.add(, ); // 同名覆盖;
  57. c.add(, , ); // 函数重载;
  58.  
  59. cout << "c.mi = " << c.mi << endl; // c.mi = 121;函数同名覆盖和重载,都是默认访问的子类的 mi;
  60.  
  61. cout << "c.Parent::mi = " << c.Parent::mi << endl; // 父类中的函数被同名覆盖,未有访问父类中的 mi;
  62.  
  63. return ;
  64. }

11,小结:

1,子类可以定义父类中的同名成员;

2,子类中的成员将隐藏父类中的同名成员;

1,包括同名成员变量和同名成员函数;

2,重写的依据;

3,这就是同名覆盖;

3,子类和父类中的函数不能构成重载关系;

1,作用域不同;

4,子类可以定义父类中完全相同的成员函数;

1,作用域不同;

5,使用作用域分辨符访问父类中的同名成员;

1,父类名加上作用域分辨符;

C++继承中的同名覆盖的更多相关文章

  1. 【转】C++中继承中的同名成员问题

    C++中,子类若有与父类同名的成员变量和成员函数,则同名的成员变量相互独立,但同名的子类成员函数重载父类的同名成员函数.举例如下: #include <iostream> using na ...

  2. C++学习笔记-继承中的构造与析构

    C++存在构造函数与析构函数,继承中也存在构造和析构函数.继承中的构造和析构函数与普通的构造析构有细微差别. 赋值兼容性原则 #include "iostream" using n ...

  3. [Java] 继承中,父类被覆盖的成员变量、方法的可访问性

    在 Java 的继承机制里,在子类内部,可以访问父类被覆盖的变量和方法:在子类外部,可以访问父类的被覆盖变量,但是不能访问父类的被覆盖方法. 父类中被覆盖的方法不能在外部被方法,这是出于封装的考虑. ...

  4. 关于Java中继承多接口同名方法的问题

    在Java中如果一个类同时继承接口A与B,并且这两个接口中具有同名方法,会怎么样? 动手做实验: interface A{ void fun(); } interface B{ void fun(); ...

  5. C++ 继承体系中的名称覆盖

    首先一个简单的样例: int x; int f() { double x; cin >> x; return x; } 在上述代码中.函数f的局部变量x掩盖了全局变量x.这得从 " ...

  6. 四. Java继承和多态3. 继承中的方法的覆盖和重载

    在类继承中,子类可以修改从父类继承来的方法,也就是说子类能创建一个与父类方法有不同功能的方法,但具有相同的名称.返回值类型.参数列表. 如果在新类中定义一个方法,其名称.返回值类型和参数列表正好与父类 ...

  7. c#和java中的方法覆盖——virtual、override、new

    多态和覆盖 多态是面向对象编程中最为重要的概念之一,而覆盖又是体现多态最重要的方面.对于像c#和java这样的面向对象编程的语言来说,实现了在编译时只检查接口是否具备,而不需关心最终的实现,即最终的实 ...

  8. Java:类与继承(隐藏和覆盖的问题)

    盒子先生金金   Java:类与继承(隐藏和覆盖的问题) Java:类与继承   Java:类与继承 对于面向对象的程序设计语言来说,类毫无疑问是其最重要的基础.抽象.封装.继承.多态这四大特性都离不 ...

  9. C++中重载、覆盖和隐藏的区别,以及适用场景

    一.重载.覆盖和隐藏的区别 二.适用场景 1.重载: 适用于不同的数据类型都需要使用到的功能函数.以数据相加的函数为例,可以在同一个文件内提供以下的重载函数以支持同样的功能: int add(int, ...

随机推荐

  1. input输入框如何只能输入非零开头的正整数

    input输入框如何只能输入非零开头的正整数 ********* 废话不多说,先来代码 ********* case1: 原生html + javascript <body> <!- ...

  2. Android 造炫目的圆形菜单 秒秒钟高仿建行圆形菜单

    1.概述 今天打开建行看存款,一看伤心欲绝,再看:我擦,这个圆形菜单挺炫.于是,为了掩盖我悲痛的心情,我决定是实现这个效果.好了,其实还有个原因,记得我初学android那会我做的应用被鄙视了,说我的 ...

  3. Selenium 环境安装

    前言: 本人在学习Selenium时,用的版本是Python3.6+Selenium3,后续写的所有学习资料都是基于这套环境.在安装Selenium3前,请确保本机已安装好了Python3,如未安装可 ...

  4. Python惯例

    “惯例”这个词指的是“习惯的做法,常规的办法,一贯的做法”,与这个词对应的英文单词叫“idiom”.由于Python跟其他很多编程语言在语法和使用上还是有比较显著的差别,因此作为一个Python开发者 ...

  5. Oracle根据列中的特殊符号进行分组

    原数据: 目标结果: 根据-符号将数据进行分组,思路是根据NAME列值进行复制,若为‘-’则赋值1,其他为0,这样就可以根据累加实现分组, 具体实现代码: /* Formatted on 2019/9 ...

  6. JavaWeb-SpringBoot_使用MySQL数据库实现用户管理_demo

    使用Gradle编译项目 传送门 项目已托管到Github上 传送门 SpringBoot使用MySQL实现 实现功能:普通用户注册.普通用户登录.管理员通过edit-user页面和show-all- ...

  7. 20175215 2018-2019-2 第四周Java课程学习总结

    第五章学习内容 1.子类的继承性 (1)子类和父类在同一包中的继承性 如果子类和父类在同一个包中,那么,子类自然地继承了其父类中不是private的成员变量作为自己的成员变量,并且也自然地继承了父类中 ...

  8. 选题 Scrum立会报告+燃尽图 05

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/8749 一.小组情况组长:贺敬文组员:彭思雨 王志文 位军营 杨萍队名:胜 ...

  9. R实现pm2.5地图数据展示

    使用rvest包抓取pm2.5静态页面数据,使用leafletCN包实现pm2.5数据的地图展示,代码如下所示: library(rvest) library(leafletCN) Sys.setlo ...

  10. anaconda 安装pyspider出错

    注释Lib\mimetypes.py里面的 try:      mimetype = mimetype.encode(default_encoding) except UnicodeEncodeErr ...