您好,欢迎来到化拓教育网。
搜索
您的当前位置:首页关于多继承

关于多继承

来源:化拓教育网


一.什么是多继承

二. 多继承下派生类的定义格式如下:

class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…
   {
    <派生类类体>
   };
class C: public A, public B
{ 
  public:
  
};   
  其中,<继承方式1>,<继承方式2>,…是三种继承方式:public、private、protected之一。

三. 多继承的构造函数

在多继承的情况下,派生类的构造函数格式如下:
  <派生类名>(<总参数表>):<基类名1>(<参数表1>),<基类名2>(<参数表2>),…
   <子对象名>(<参数表n+1>),…
    {
     <派生类构造函数体>
    }
  其中,<总参数表>中各个参数包含了其后的各个分参数表。

四.派生类构造函数执行顺序

1.先执行所属基类的构造函数
2.再执行派生类本身构造函数 

注:执行基类构造函数的顺序取决于定义派生类时基类的顺序 

//代码1(代码1和代码2对比)
#include<iostream> 
using namespace std; 
class A 
{ 
  public:
   A()
 {
   cout<<"A's constructor"<<endl;
   } 
}; 
class B
{ 
  public: 
  B()
  {
    cout<<"B's constructor"<<endl;
	} 
};  
class C: public A, public B//先A后B 
{ 
  public:
  C()
  {
    cout<<"C's constructor"<<endl;
	} 
};  
int main()
{
   C c;
   return 0;
} 
//输出"A's constructor"然后是"B's constructor"最后是"C's constructor"
//代码2
#include<iostream> 
using namespace std; 
class A 
{ 
public:
   A()
 {
   cout<<"A's constructor"<<endl;
   } 
}; 
class B
{ 
public: 
  B()
  {
    cout<<"B's constructor"<<endl;
	} 
};  
class C: public B, public A//先B后A 
{ 
   public:
   C()
   {
     cout<<"C's constructor"<<endl;
	 } 
};  
int main()
{
   C c;
   return 0;
} 
//先输出"B's constructor"再输出"A's constructor"最后输出"C's constructor"
#include<iostream> 
using namespace std; 
class A 
{ 
   int a;
   public:
   A(int x)
      {
	    a=x;
		cout<<"A's constructor"<<endl;
	  } 
	int geta()
	{
		return a;
	}
}; 
class B
{ 
  int b;
   public: B(int y)
       {
	     b=y;
		 cout<<"B's constructor"<<endl;
		 } 
    int getb()
    {
    	return b;
	}
};  
class C: public A, public B
{ 
  int c;
   public:C(int x,int y,int z):B(x),A(y)
	   {
	     z=c;
		 cout<<"C's constructor"<<endl;
		} 
};  
int main()
{
   C c(1,2,3);
   A a1(5);
   cout<<c.geta()<<endl<<c.getb()<<endl;
   cout<<a1.geta()<<endl; 
   cout<<c.geta();
   return 0;
} 

五. 二义性问题

  • 第一种:

  • 同名二义性:在继承时,基类之间、或基类与派生类之间发生成员同名时,将出现对成员访问的不确定性

//错误代码举例: 
#include <iostream>
using namespace std;
class A
{
public:
    void show()
    {
        cout<<"This is A";
    }
};
class B
{
public:
    void show()
    {
        cout<<"This is B";
    }
};
class Son:public A,public B
{
public:
    void display()
    {
        cout<<"This is son\n";
    }
};
int main()
{
    Son son;
    son.show();//错误,因为不知道访问类A中的show(),还是访问类B中的show() 
    son.display();
    cout << "Hello world!" << endl;
    return 0;
} 
  • 解决方法一:利用作用域限定符::,用来限定派生类类调用的是哪个基类的show()函数

son.show()   ===> son.A::show()或者son.B::show()
//正确代码举例:son.A::show() 
#include <iostream>
using namespace std;
class A
{
public:
    void show()
    {
        cout<<"This is A"<<endl;
    }
};
class B
{
public:
    void show()
    {
        cout<<"This is B"<<endl;
    }
};
class Son:public A,public B
{
public:
    void display()
    {
        cout<<"This is son"<<endl;
    }
};
int main()
{
    Son son;
    son.A::show();
    son.display();
    cout << "Hello world!" << endl;
    return 0;
}
  • 解决方法二:在派生类中定义同名成员,覆盖掉基类中的相关成员

//正确代码举例:
 #include <iostream>
using namespace std;
class A
{
public:
    void show()
    {
        cout<<"This is A"<<endl;
    }
};
class B
{
public:
    void show()
    {
        cout<<"This is B"<<endl;
    }
};
class Son:public A,public B
{
public:
    void display()
    {
        cout<<"This is son"<<endl;
    }
    void show()
    {
        cout<<"show::This is son"<<endl;
    }
};
int main()
{
    Son son;
    son.show();//此时son.show()将调用son.Son::show() 
    son.display();
    cout << "Hello world!" << endl;
    return 0;
}
  • 第二种:

  • 路径二义性: 有最基类A,有A的派生类B、C,又有D同时继承B、C,那么若A中有成员m,那么在派生类B,C中就存在m,又D继承了B,C,那么D中便同时存在B继承A的m和C继承A的m,那么当D的实例调用m的时候就不知道该调用B的m还是C的m,就导致了二义性。

//错误代码
#include <iostream>
using namespace std; 
class A
{
public:
    int m;
};
class B:public A {};
class C:public A {};
 
class D:public B,public C {};
 
int main()
{
    D d;
    d.m= 10;//错误,因为不知道调用B的m还是C的m 
    cout << "Hello world!" << endl;
    return 0;
}
  • 解决方法一:使用作用域限定符,指明访问的是哪一个基类的成员

d.m= 10   ====>  d.B::m= 10或者d.C::m= 10
#include <iostream>
using namespace std; 
class A
{
public:
    int m;
};
class B:public A {};
class C:public A {};
class D:public B,public C {};
 
int main()
{
    D d;
    d.B::m= 10;
    cout << "Hello world!" << endl;
    return 0;
}
  • 解决方法二:在派生类中D定义同名成员,覆盖掉父类中的相关成员

class A
{
public:
    int m;
};
class B:public A {};
class C:public A {};
class D:public B,public C
 {
 	public:
 	int m; 
 };
//正确代码举例
#include <iostream>
using namespace std; 
class A
{
public:
    int m;
};
class B:public A {};
class C:public A {};
class D:public B,public C
 {
 	public:
 	int m; 
 };
int main()
{
    D d;
    d.m= 10;//此处相当于访问的D的m 
    cout<<d.D::m<<endl; 
    cout<<"Hello world!"<<endl;
    return 0;
}  
  • 解决方法三:虚继承、使用虚基类

#include <iostream>
using namespace std; 
class A
{
public:
    int m;
};
class B:virtual public A {};
class C:virtual public A {};
class D:public B,public C
 {
 	public:
 	int m; 
 };
int main()
{
    D d;
    d.m= 10;
    cout<<"Hello world!"<<endl;
    return 0;
} 

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo9.cn 版权所有 赣ICP备2023008801号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务