⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ex22.cpp

📁 C/C++程序设计教程
💻 CPP
字号:
	     
          //第22章 多重继承和类型变换

//[例22.1]多个直接基类
    #include<stdio.h>
	struct CBase1
	{	CBase1(int n=1){m_b1=n;printf("CBase1::CBase1()this=%p,%p\n",this,&m_b1);}
		void  Show() 
         {printf("%d.CBase1::Show() sizeof(CBase1)=%d\n",m_b1,sizeof(CBase1));}
		int m_b1; 
	};
	class CBase2  
	{	public:	CBase2(int n=2)
              {m_b2=n;printf("CBase2::CBase2()this=%p,%p\n",this,&m_b2);}
		void  Show()
        {printf("%d.CBase2::Show() sizeof(CBase2)=%d\n",m_b2,sizeof(CBase2));}
		long l;    
	    protected:  int m_b2;
	};
	class CDerived:public CBase2, virtual public CBase1
	{	public:CDerived(int n=3)
			{m_d=n;printf("CDerive::CDeriv this=%p,%p\n",this,&m_d);}
		int m_d;	 		
	    int Show();	 
	};
	int CDerived::Show()
	{	CBase1::Show();        CBase2::Show();
		printf("%d.CDerived::Show() sizeof(CDerived)=%d\n",m_d,sizeof(CDerived));	
		return 0;
	}
     void main()	     {	 CDerived d; 		 d.Show();		 }
//[例22.2]关键字virtual对多重继承的影响。从输出结果注意构造函数调用的次序。 
     #include<stdio.h>
    class CTop
	{   public:	int mt;
        CTop(int n=0)	 {mt=n;printf("%d.CTop()this=%p,%p\n",mt,this,&mt);}
	};
	struct CBase1:virtual public CTop
	{	CBase1(int n=1)	{b1=n;printf("CBase1()this=%p,%p\n",this,&b1);}
		void  Show() 
		{printf("%d.CBase1::Show()sizeof(CBase1)=%d\n",b1,sizeof(CBase1));}
		int b1; 
	};
	class CBase2: public virtual 	CTop 
	{	public:	CBase2 (int n=2){b2=n;printf("CBase2()this=%p,%p\n",this,&b2);}
		void  Show()
		{printf("%d.CBase2::Show()sizeof(CBase2)=%d\n",b2,sizeof(CBase2));}
		long l;    	    protected:  int b2;
	};
	class ClassD:public CBase1,public CBase2
	{	public:	 int d;	 	
		ClassD(int n=3){d=n;printf("ClassD()this=%p,%p\n",this,&d);}
	    int Show();	 
	};
	int ClassD::Show()
	{	CBase1::Show();		CBase2::Show();
		printf("%d.ClassD::Show()sizeof(ClassD)=%d\n",d,sizeof(ClassD));	
		return 0;
	}
     void main()	 {	 ClassD d;	d.Show();	}
//[例22.3]非虚拟继承两个基类同时包含两个嵌入对象的派生类
    #include <stdio.h> //先调用基类的构造函数然后调用派生类嵌入对象的构造函数。
	struct A	{  A(int n=1){printf("A=%d,",n);}}; //首先根据声明的次序分别调用
    struct B	{  B(int n=2){printf("B=%d,",n);}}; //基类A,B的构造函数
   	struct D:public A,public B                  //基类构造函数的次序为A,B
	{    D(int n,int m): A(n),b(m)             //构造函数定义, 仅显式调用A(n),b(m)
		  {printf("D=%d\n",n+m);}//包容类D的构造函数后于嵌入对象的构造函数被调用
	     B b;   A a;                       //声明两个嵌入结构变量,次序为b,a
    };                                     //嵌入对象构造函数的调用次序为B,A
    void main(){ D d(100,200);}                //输出:A=100,B=2,B=200,A=1,D=300
   //[例22.4]多继承间接基类的初始化
    #include<stdio.h>
    class CTop	                                      //虚拟继承的树层次//
	{   public: int m_t;
		CTop(int n=0)
		{ m_t=n; printf("%d.CTop=%d,",m_t,sizeof(CTop));}
	};
	struct CBase1:virtual public CTop
	{   int m_b1;
		CBase1(int n=1):CTop(n)                            
		{ m_b1=n;printf("%d.CBase1=%d,",m_b1,sizeof(CBase1));}
	};	class CBase2: public virtual CTop 	{  public:	CBase2 (int n=2):CTop(n)		{  m_b2=n; printf("%d.CBase2=%d,",m_b2,sizeof(CBase2));}		protected:  int m_b2;	};	class CDerived:public CBase1,public CBase2	{  public:	                                     	
        CDerived(int n):CBase2(n-3),CBase1(n-2),CTop(n-1)//构造函数初始化
		{m_d=n;	printf("%d.CDerived=%d\n",m_d,sizeof(CDerived));}
	   int m_d;	 		  
	};
    void main()	 {CDerived   d(4)	; 	}
CDerived(int n):CBase2(n-3),CBase1(n-2)
		{m_d=n;	printf("%d.CDerived=%d\n",m_d,sizeof(CDerived));}
//[例22.5]不唯一的名称m_n,Set,f()可产生二义性。
	#include<stdio.h>
     class A    {    public:  void f(){}	    };	      class B:public  A{ public : void f(){}
	    public : int m_n;	      void Set(int n){ m_n=n;	} };
    struct C	{  int m_n; 		  void Set(int n){m_n=n;	} };
	class D:public C,public B
	{  public:	 int m_d;		   void Set(int n){m_d=n;}  };
    //[例22.6]清除名称二义性的途径
   class CTop		           { public:	int m_t; };
   struct CBase1:	public CTop	{int m_b1;};
   class CBase2:  public  CTop {protected:  int m_b2;	};
	class CDerived:public CBase1,public Cbase2
	{		public:    int m_d;	 		  	};

//[例22.7]动态类型变换
	#include <stdio.h>  
	class ClassB 
	{ public:	 long  m_n;
	  public:	ClassB() {m_n=1;}
				virtual		f(){}              //设置一个虚函数是必要的
		void Show(){printf("ClassB::m_n=%d\t",m_n);}	//此时Show不是虚函数
    };   
	class ClassC:public ClassB 
	{   	public:	ClassC() {m_n=2;}	
	    void Show(){printf("ClassC::m_n=%d\t",m_n);}		 
   	};  
    class ClassD:public ClassC
	{	 public:ClassD() {m_n=3;}	
	    void Show(){printf("ClassD::m_n=%d\t",m_n);}	
	};	
	void fcast(ClassB* pObj)
	{	ClassC* pObjc=dynamic_cast<ClassC*>(pObj) ;
    	if(pObjc!=NULL) pObjc->Show();
	}
	void main()
	{	ClassB objb;         fcast(&objb);
        ClassB *pObjb=new 	ClassD();//pObjb具有动态类型为ClassD*
	    fcast(pObjb);
		((ClassD*)pObjb)->Show();     //将pObjb真正变换到原来的对象地址
        ClassC objc;  	    fcast(&objc);
	}		//输出:ClassC::m_n=3   ClassD::m_n=3       ClassC::m_n=2
//[例22.8]引用形式的动态类型变换
	#include <stdio.h>  
    #include<typeinfo.h>
	class ClassB 
	{	 public:	 long  m_n;
	    public:	ClassB() {m_n=1;}
	virtual	void Show(){printf("ClassB::m_n=%d\n",m_n);}	//该题Show是虚函数
    };   
	class ClassC:public ClassB 
	{   	public:	ClassC() {m_n=2;}	
	    void Show(){printf("ClassC::m_n=%d\n",m_n);}		 
   	};  	
    class ClassD:public ClassC
	{	 public:ClassD() {m_n=3;}	
	    void Show(){printf("ClassD::m_n=%d\n",m_n);}
		~ClassD() {printf("~ClassD;\n");}	
	};	
	void fcast(ClassB& rObj)
	{     try{
	      ClassC& rObjc=dynamic_cast<ClassC&>(rObj) ;
	      rObjc.Show();
	     }
	   catch(bad_cast)	   {	   printf("bad_cast produced\n");	   }
	}
	void main()
	{	ClassB objb;   fcast(objb);           //程序输出结果:
        ClassB* pObjb=new 	ClassD();      //bad_cast produced
	    fcast(*pObjb); //动态绑定发生作用      // ClassD::m_n=3
		((ClassD&)*pObjb).Show();           //ClassD::m_n=3
        ClassC objc;                        // ClassC::m_n=2
	    fcast(objc);                          // ~ClassD;
        delete (ClassD*)pObjb;
	}
//[例22.9]继承层次的静态类型变换
	#include <stdio.h>  
	class ClassB 
	{	 public:	 long  m_n;
	    public:	ClassB() {m_n=1;}
	//virtual		                      // 去掉双斜杠Show()为虚函数
		void Show(){printf("ClassB::m_n=%d\n",m_n);}	
    };   
	class ClassC:public ClassB 
	{   	public:	ClassC() {m_n=2;}	
	    void Show(){printf("ClassC::m_n=%d\n",m_n);}		 
   	};  
    class ClassD:public ClassC
	{	 public:ClassD() {m_n=3;}	
	    void Show(){printf("ClassD::m_n=%d\n",m_n);}
		~ClassD() {printf("~ClassD;\n");}	
	};	
	void fcastb(ClassB& rObj,int n)
	{	if(n==1)	{   ClassC& rObjc=static_cast<ClassC&>(rObj) ;//引用变换语法
			          rObjc.Show();				}
		else	   {   ClassC& rObjc=(ClassC&)(rObj) ;        //C形式的变换格式
		             rObjc.Show();	          } 
	}                                      //上面if分支两种变换格式效果是等价的
	void fcasta(ClassB* pObj,int n)            //下面if分支两种变换格式效果是等价的
	{   ClassC* pObjc;
		if(n==1) pObjc=static_cast<ClassC*>(pObj) ;		    //指针变换语法
		else     pObjc=(ClassC*)(pObj) ;		            //C形式的转换格式
		pObjc->Show();	
	}
	void fa()                              //显示指针类型静态变换
	{	ClassB objb;                         fcasta(&objb,1);
        ClassB* pObjb=new 	ClassD();	    fcasta(pObjb,1);
        ClassC objc;   	                     fcasta(&objc,1);      
	    delete (ClassD*)pObjb;
	}
    void fb()                                //显示引用形式静态类型变换    
	{ 	ClassB objb;                         fcastb(objb,1);
        ClassB* pObjb=new 	ClassD();	    fcastb(*pObjb,2);
        ClassC objc;  	                      fcastb(objc,1);      		
	}
	void main(){      fa();       fb();           }
//[例22.10]简单变量的静态类型变换
    #include <stdio.h>
    void f(short  v)  { printf("%d\t",v);}   
	void f(float  f)  { printf("%f\n",f);}     
    void main()       
    {    long l=10;    double d=20;
        f( static_cast<short>(l)); 
	    f( static_cast< float >(d));
	}        //程序输出结果:10   20.000000
//[例22.11]简单变量的指针和引用变换
    #include <stdio.h>
    void f(short&   v)  { printf("%d\t",v);}   
	void f(double*  p)  { printf("%f\t",*p);}  
	void main()       
    {    long l=10;    float tf=20.0f;
        f(reinterpret_cast<short&>(l)); 
	    f(reinterpret_cast<double*>(&tf));
	    f((short&)l);    printf("*((double*)&tf)=%f\t",*((double*)&tf));
	    f((double*)(&tf));	
	}//////////////程序运行输出结果://///////////////////
//[例22.12]松动实参const属性的变换
    #include <stdio.h>   
	void fc(int*  p)  { printf("%d\t",*p);}//函数中没有改变间接变量的值
	void fc(int&  v)  { printf("%d\n",v);} // 函数中v作为右值出现
	void main()           //d具有const int型的类型属性
    {   const int d=20;// &d的地址具有const int *型的类型属性
	    fc( const_cast<int*>(&d));	//效果上等价于fc( (int*)&d);
		fc( const_cast<int&>(d));  	//效果上等价于fc( (int&)d);	
	}         //输出结果:20  20
//[例22.13]typeid显示表达式的类型信息	
    #include <stdio.h>  
    #include<typeinfo.h>
	class ClassB                            //多态类之根基类
	{	public:	virtual void SetB(){m_b=1;}		
		int m_b;
	};
	class ClassC : public ClassB             //多态类继承体系之派生类
	{	public:	void SetB(){m_c=2;}	int m_c;   	};	
	void main()
	{  double d;     
        if(typeid(int) !=typeid(double*))
		   if(typeid(&d) ==typeid(double*))  printf("%s\t", typeid(double*).name());     
		if(typeid('1')==typeid(char))         printf("%s\t", typeid('1').name());
		long n;      	
		float& rn=(float&)n;                 //内置数据变量不进行动态类型跟踪
			printf("%s,\t%s\t", typeid(n).name(),typeid(rn).name());
		ClassB b;  	ClassC c;
		ClassB& rb=c;                  //引用rb的动态类型为 class  ClassC
			printf("%s,\t%s\t", typeid(b).name(),typeid(rb).name());
	}//输出:double*    char    long,   float    class  ClassB, class  ClassC
//[例22.14]before和raw_name()成员函数
    #include <stdio.h>  
    #include<typeinfo.h>
    #include<string.h>
	class ClassB 
	{	public:		virtual void SetB(){m_b=1;}		
		int m_b;
	};
	class ClassC : public ClassB
	{	public:	int m_c;  
		    void SetB(){m_c=2;}	  
	};	
    void f1(int,float){}
	void f2(ClassC*,long){}
	void main()
	{	double d=1;  
	   const type_info& t1=typeid(f1);    const type_info& t2=typeid(f2);
	printf("%s,\t%s\n", t1.name(),t1.raw_name());    
	printf("%s,\t%s\n", t2.name(),t2.raw_name()); 
	ClassC c;	ClassB& rb=c;
	const type_info& tc=typeid(ClassC*);   // typeid(e)是const对象,别名也是const属性
	const type_info& tb=typeid(rb);          //声明typeid(rb)的别名tb简化代码书写量
    if(t1.before(t2))
              printf("1--t1.before(t2)\t");
	if(strcmp(t1.raw_name(),t2.raw_name())<0) 
              printf("2--t1.before(t2)\n");
    if(tb.before(tc)) 
             printf("3--%s,\t%s\t", tb.name(),tc.name()); 
	 if(strcmp(tb.raw_name(),tc.raw_name())<0) 
           printf("4--%s,\t%s\n", tb.name(),tc.name()); 
	 void* vp=&d; 
   	 printf("%s,\t%s\n", typeid(vp).name(),typeid(*(double*)vp).name()); 
	}///////////////输出结果://///////////////////



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -