转自:http://www.cnblogs.com/lintong/archive/2012/07/28/2613002.html

1. 什么是多重继承的二义性

  1. class A{
  2. public:
  3. void f();
  4. }
  5.  
  6. class B{
  7. public:
  8. void f();
  9. void g();
  10. }
  11.  
  12. class C:public A,public B{
  13. public:
  14. void g();
  15. void h();
  16. };

如果声明:C c1,则c1.f();具有二义性,而c1.g();无二义性(同名覆盖)。

2. 解决办法一 -- 类名限定

调用时指名调用的是哪个类的函数,如

  1. c1.A::f();
  2. c1.B::f();

3. 解决办法二 -- 同名覆盖

在C中声明一个同名函数,该函数根据需要内部调用A的f或者是B的f。如

  1. class C:public A,public B{
  2. public:
  3. void g();
  4. void h();
  5. void f(){
  6. A::f();
  7. }
  8. };

4. 解决办法三 -- 虚基类(用于有共同基类的场合)
virtual 修饰说明基类,如:

  1. class B1:virtual public B

虚基类主要用来解决多继承时,可能对同一基类继承继承多次从而产生的二义性。为最远的派生类提供唯一的基类成员,而不重复产生多次拷贝。注意:需要在第一次继承时就要将共同的基类设计为虚基类。虚基类及其派生类构造函数建立对象时所指定的类称为最(远)派生类。

  • 虚基类的成员是由派生类的构造函数通过调用虚基类的构造函数进行初始化的。
  • 在整个继承结构中,直接或间接继承虚基类的所有派生类,都必须在构造函数的成员初始化表中给出对虚基类的构造函数的调用。如果未列出,则表示调用该虚基类的缺省构造函数。
  • 在建立对象时,只有最派生类的构造函数调用虚基类的构造函数,该派生类的其他基类对虚基类的构造函数的调用被忽略。
  1. class B{
  2. public:
  3. int b;
  4. }
  5.  
  6. class B1:virtual public B{
  7. priavte:
  8. int b1;
  9. }
  10.  
  11. class B2:virutual public B{
  12. private:
  13. int b2;
  14. }
  15.  
  16. class C:public B1,public B1{
  17. private:
  18. float d;
  19. }
  20.  
  21. C obj;
  22. obj.b;//正确的

如果B1和B2不采用虚继续,则编译出错,提示“request for member 'b' is ambiguous”。这是因为,不指名virtual的继承,子类将父类的成员都复制到自己的空间中,所以,C中会有两个b。

  1. #include<iostream>
  2. using namespace std;
  3.  
  4. class B0{
  5. public:
  6. B0(int n) {
  7. nv=n;
  8. cout<<"i am B0,my num is"<<nv<<endl;
  9. }
  10. void fun() {
  11. cout<<"Member of Bo"<<endl;
  12. }
  13. private:
  14. int nv;
  15. };
  16.  
  17. class B1:virtual public B0{
  18. public:
  19. B1(int x,int y):B0(y){
  20. nv1=x;
  21. cout<<"i am B1,my num is "<<nv1<<endl;
  22. }
  23. private:
  24. int nv1;
  25. };
  26.  
  27. class B2:virtual public B0{
  28. public:
  29. B2(int x,int y):B0(y){
  30. nv2=x;
  31. cout<<"i am B2,my num is "<<nv2<<endl;
  32. }
  33. private:
  34. int nv2;
  35. };
  36.  
  37. class D:public B1,public B2{
  38. public:
  39. D(int x,int y,int z,int k):B0(x),B1(y,y),B2(z,y){
  40. nvd=k;
  41. cout<<"i am D,my num is "<<nvd<<endl;
  42. }
  43. private:
  44. int nvd;
  45. };
  46.  
  47. int main(){
  48. D d(1,2,3,4);
  49. d.fun();
  50. return 0;
  51. }

d.fun()的结果是:

  1. i am B0,my num is 1
  2. i am B1,my num is 2
  3. i am B2,my num is 3
  4. i am D,my num is 4
  5. Member of Bo

【转】C++中多重继承的二义性及解决办法的更多相关文章

  1. c++,多继承造成的二义性及解决办法

    #include <iostream> using namespace std; //------------------------------- class A1{ public: i ...

  2. iOS 学习笔记二【cocopods安装使用和安装过程中遇到的问题及解决办法】【20160725更新】

    在osx 10.11之前cocopods问题不多,但是升级到11之后的版本,之前的cocopods大多用不了,需要重新安装,对于我这种使用测试版系统的技术狂来说,每次都需要重新安装很多东西, 当然,c ...

  3. MyEclipse代码编辑器中汉字太小的解决办法(中文看不清)

    问题描述:新安装的myeclipse 2014,代码编辑器中汉字很小看不清 解决办法:调整字体即可.通过菜单Windows——Preferences,输入font过滤选择Colors and Font ...

  4. 虚拟机中不能连接usb设备解决办法

    虚拟机中不能连接usb设备解决办法 1.点击开始->运行,在对话框中输入"services.msc",确定,打开windows服务管理器.2.在服务列表中选中"VM ...

  5. Aasible中cryptography兼容性报错解决办法

    Aasible中cryptography兼容性报错解决办法 1 Ansible中使用ansible --version查看版本,报错信息如下: ERROR! Unexpected Exception, ...

  6. windows10中git-bash闪退的解决办法

    windows10中git-bash闪退的解决办法 出现错误详情 Windows10 64位专业版安装git .18之后出现 Git闪退,报错信息:bash: /dev/null: No such d ...

  7. SVN版本冲突中 Files 的值“ < < < < < < < .mine”无效路径中具有非法字符的解决办法

    .NET 中 SVN版本冲突中 Files 的值“ < < < < < < < .mine”无效路径中具有非法字符的解决办法: 一. 1.将项目逐个进行编译, ...

  8. RS错误RSV-VAL-0032之项目未在布局中引用的3种解决办法

    如下图所示,我用RS新建了一个空白页面,拖入了一个列表,给该列表新建了一个条件样式 条件样式如下所示,表达式来自查询1 运行,报错如下图所示 原因就是条件样式使用到了查询1中的数据项1但是数据项1在报 ...

  9. iOS cocopods安装使用和安装过程中遇到的问题及解决办法

    在osx 10.11之前cocopods问题不多,但是升级到11之后的版本,之前的cocopods大多用不了,需要重新安装,对于我这种使用测试版系统的技术狂来说,每次都需要重新安装很多东西, 当然,c ...

随机推荐

  1. ***PHP各种编码的汉字字符串截取

    虽然PHP有现成的截取字符串函数substr(),但是这个函数不能对汉字字符串进行截取,要实现这种效果还需要我们自己去编写相应的函数.汉字有多种编码,比如GB2312,UTF-8等,汉字字符串的截取需 ...

  2. HDOJ多校联合第四场

    B题: C题:仅由'A','G','C','T',4个字母组成,给定一个字符串S,|S|<=15,给定一个整数m,以m为长度且仅含4种字母的字符串T,求LCS(S,T)为0,1,2,3....| ...

  3. 去除Coding4Fun中MessagePrompt的边框(Border)

    在App.xaml文件中添加 xmlns:c4f="clr-namespace:Coding4Fun.Toolkit.Controls;assembly=Coding4Fun.Toolkit ...

  4. 学习笔记-[Maven实战]-第三章:Maven使用入门(2)

    使用maven执行编译和测试 1.maven执行编译 (1).在pom.xml上点右键,选择Maven build... (2).在Goals里输入clean complie,执行编译 执行结果: [ ...

  5. 【HDOJ】3505 Writing Robot

    挺好的一道题目,我的做法是kmp+Dinic网络流.kmp求子串在P中出现的次数,从而计算love值.网络流主要用来处理最优解.case2中p1的love值是8,p2的love值是7,最终T包含p1和 ...

  6. C#微信公众号开发系列教程(接收事件推送与消息排重)

    微信服务器在5秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次.这样的话,问题就来了.有这样一个场景:当用户关注微信账号时,获取当前用户信息,然后将信息写到数据库中.类似于pc端网站的注册.可 ...

  7. BZOJ_1012_[JSOI2008]_最大数maxnumber_(线段树/树状数组+RMQ)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1012 两种操作: 1.求序列末尾n个数中的最大值. 2.在序列末尾插入一个数. 分析 线段树求 ...

  8. MVC3.0 中Razor 学习

    随着MVC3.0RTM版本的发布,最近将公司的项目从MVC2.0升级到MVC3.0.同时打算在MVC3中全面使用Razor模板引擎.现将Razor学习拿出来和大家分享,如果存在不足的地方欢迎您指出. ...

  9. [BILL WEI]一些经常用到的SQL函数

    截取时间 --convert可以截取特点值 convert(varchar(10),getdate(),120) 截取2012-11-11 11:11:11 前10位,得到日期2012-11-11

  10. DataProvider 传递参数

    package roger.testng; import org.testng.annotations.DataProvider; import org.testng.annotations.Test ...