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

📄 ex15.cpp

📁 这里有大量的习题解答
💻 CPP
字号:
			
         	//第15章  特殊的成员函数


    //[例15.1]定义对象数组CA a[2];导致两次调用缺省构造函数。程序输出:2,3,13
    #include <stdio.h>        //定义对象b(10)调用构造函数CA(int m),m=10
    static int cx=1;   const int constn=0;//cx是静态全局变量,constn是整型立即数
	class CA	{ public: CA(int m=1){x= constn +m+cx++; }    long  x;  	} ;                   
    void main() {  CA a[2],b(10);   printf("%d,%d,%d",a[0].x,(a+1)->x,b.x);  }

//[例15.2]构造函数的调用
    #include <stdio.h>  
    static int n=0;                    //静态的全局变量n纪录构造函数调用次数
    class CType
	{  	  public:	CType(){m_n=n++; }
	  int m_n;	
	};
	CType d;                //定义全局对象d,d调用构造函数一次,使得n变化为1
	void fs(){static CType s;printf("s.%d\t",s.m_n);} //静态对象最多仅调用一次构造函数
	void fa(){CType a ;printf("a.%d\t",a.m_n);} //非静态的局部对象a每次都调用构造函数
	void main()	{    fs();   fs();    fa();   fa();	   }
//	 输出:s.1 	 s.1	    a.2   a.3
////////////[例15.3] 函数对象名语法
	#include <stdio.h>  
    #include<string.h>
    class CType
	{  int m_n;	
	  public:	CType(int n=1){m_n=n; }            //单参构造函数内置定义     
		void  operator()(const CType* s);          //函数名为operator()的成员函数 
		void Show(char*s)	 {printf("%s,n=%d\t",s,m_n);}
	};
	void CType::operator()(const CType* s) // const CType* 入口形参为指向对象的指针
	{                                // operator()是函数调用()运算符函数
      memcpy(this,s,sizeof(CType));	     //此函数执行对象数据的拷贝功能  
	}
	CType d();                 //全局函数原型说明,这是一个未被调用的函数。
	void main()
	{   CType d(1);              //定义局部对象d,d调用构造函数CType(int)
		d.Show("d(1)");           //对象调用成员函数Show(char*s)
		CType *p=new CType(2);  //先调用new函数,new调用构造函数CType(int)
		d(p); d.Show("d(p)");       // d(p)函数对象名语法调用成员函数operator()
	    d=CType(3); d.Show("CType(3)");// d=CType(3)为显式调用构造函数CType(int) 
	    CType(4).Show("CType(4)"); //无名对象CType(4)调用成员函数Show(char*)        
	}	//输出:d(1),n=1 		 d(p),n=2     CType(3),n=3    CType(4),n=4

//////////[例15.4] 构造函数的显式调用构成初始化列表
    #include <stdio.h>  
    static int cnum=1;     static int cx=-1,cy=-1;
	struct CA
	{  CA()  { x=cx--; y=cy--; printf("%d.CA(%d,%d);\n",cnum++,x,y);}
       CA(int m,int n){x=m;y=n;  printf("%d.CA(+%d,+%d);\n",cnum++,x,y);}
	   long  v(){ return x; }
	   private:			long  x;        long  y;
	} ;                                   /*程序运行输出结果:*/
    void main()                            /*1. CA(-1,-1);*/
	{  CA a[2];                           /*2. CA(-2,-2);*/
	   CA d[3]={CA(1,1),CA(2,2)};          /*3. CA(+1,+1);*/
	    d[2]=CA(3,3);                      /*4. CA(+2,+2);*/
	   if(d[1].v()==(d+1)->v())               /*5. CA(-3,-3); */
	   printf("d[1].v()=(d+1)->v()");           /*6. CA(+3,+3);*/
	}                                     /*d[1].v()=(d+1)->v()*/     
/////////////[例15.5]对象定义与析构函数
	#include <stdio.h>  
    static int numc=0;                    //静态全局变量纪录析构函数的反序调用次数
	class CType 
	{   public: CType(int=3 );                  //缺省值为3的构造函数	
		~CType();                      //析构函数无参也无返回类型
	    private:  long * m_p;             //一个指针成员用于定位动态数组
		 int  m_n;                       //描述动态数组的动态维数
     };   
	CType::CType(int n)                //单个参数入口的构造函数
	{	m_n=n;
		printf("%d,CType();++%d\n",m_n,++numc);	
        m_p=new long[m_n];             //构造函数中分配动态数组的内存空间
	}	
	CType::~CType()
	{	printf("%d,~CType();%d--;",m_n,numc--);		
        delete [] m_p;                   //清除动态long型数组的内存空间
	}
	 CType g(1);	                             //定义全局对象g,调用CType(1)
     CType *q=new CType(9); //定义堆中对象*q,这个*q对象没有被delete q清除
	void main()             //因此相应的析构函数未被调用
	{	printf("Enter into main(){\n");             //进入主函数的势力范围
		CType d(2);			                //定义局部对象d,调用CType(2)
		CType *pk=new CType[2];            //定义两个堆中对象,2次调用CType(3)
	    delete  [] pk;                       //清除此数组的两个对象
		printf("\nGo  outof main() }\n");        //退出主函数的作用范围   
	}       //程序运行输出结果:
//////////////[例15.6] 赋值运算符函数与拷贝构造函数
	#include <stdio.h>  
    #include<string.h>	
    class B
	{private:int	m_n;	 
	 public:	B(int v=1){Set(v); }	                          //单参数缺省构造函数
		B(const B& r);		                              //拷贝构造函数
        B& operator=(const B& r);                        //等号运算符函数
		void Set(int n){m_n=n; }                          //设置成员变量的函数
		void Show()    {printf("n=%d;",m_n);}            //显示成员状况的函数 
	};	
	B::B(const B& r)                                 //拷贝构造函数copy constructor
	{  printf("call B::B(const B& r);");                   //屏显语句通常是多余的
     memcpy(this,&r,sizeof(B)); //调用内存拷贝函数,this指向调用成员函数的对象地址
	}                        //调用成员函数的对象即当前对象
   	B& B::operator=(const B& r)                       //assignment函数
	{ printf("call B& B::operator=(const B& r);");
	  if(this==&r) return *this;   //如果入口r的地址等于当前对象的地址,返回当前对象
      memcpy(this,&r,sizeof(B)); //简单的内存拷贝	
	  return *this;             // return *this返回调用该成员函数的对象
	}	//this此时是B*const型的指针,间接对象*this即当前对象是B型左值
    void main()
	{	 B d;                                 //调用有缺省值的构造函数B(int v=1)
		 d.Show();                             //显示d(1)初始化后的结果
		 B a=d;                               //调用拷贝构造函数B(const B& r)
		 a.Show();                             //显示a(d)初始化后的结果
		 a.Set(100);                            //将a.m_n设置为100
		 d=a;                                 //调用函数B& operator=(const B& r);
		 d.Show();
	}	//输出:n=1;call B::B(const B& r);n=1; call B& B::operator=(const B& r);n=100
////////////	[例15.7]拷贝构造函数的隐含作用  
	class A 
    {  public:			A(int n)      {   	m_n=n;	}		
                 ~A()      {	}//这相当于编译器提交的缺省析构函数
	   private:   	    A(const A& r) {   m_n=r.m_n;   }		
		 int  m_n; 
   	};   
	void f(A  a)  { }
	A  g(int n)  {     return A(n); }    //error : cannot access private member
	void main()
	{   A  d(2);				A  b=10;
        A   a=d; //error : cannot access private member
		f(b);    // error :cannot access private member		
	}

///////////[例15.8] CRect类中的重载函数SetRect
	#include<string.h>
	#include<stdio.h>
	class CRect
	{	public:		long    left;   long    top;
		            long    right;  long    bottom;
		CRect(int l=1, int t=2, int r=3, int b=4);			
        void SetRect(int x1, int y1, int x2, int y2);
		void SetRect(const CRect& r) ;
        void Show();		
	};
	void CRect::Show()                     //成员函数显示自身的数据
	{
	printf("left=%d,top=%d,right=%d,bottom=%d;", left,top,right,bottom);
	}
    void CRect::SetRect(const CRect& r)   //设置矩形函数
	{ 
      left =r.left;	 top = r.top;	right = r.right;	 bottom = r.bottom;
	}
	 CRect::CRect(int l, int t, int r, int b) //带参构造函数缺省值全部设置
	{	  SetRect(l,t,r,b);    }      //构造函数调用自身的成员函数	
    void CRect::SetRect(int l, int t, int right, int bottom)
	{                                   //设置矩形坐标值的成员函数
	  left = l; top = t;   this->right = right;  this->bottom = bottom;
	}
	void main()
	{	CRect r,s;            //定义对象导致调用构造函数CRect(1, 2, 3, 4)
		r.Show();                   //r对象显示数据
		r.SetRect(5,6,7,8);          //调用成员函数SetRect(int , int , int, int)
	    s.SetRect(r);                //调用成员函数SetRect(const CRect& r)
        s.Show();                   //s对象显示数据
	} //输出:left=1,top=2,right=3,bottom=4;left=5,top=6,right=7,bottom=8

///[例15.9]缺省参量的构造函数和成员函数
	#include<stdio.h>
	class CType
    {		 long m;  int n;   short s;
	public:	 void   Set(int n,long m=10,short s=5);
		     CType(int n=1,long m=10,short s=5);// 全部设置缺省值的构造函数
			 void   Show();
			 CType(){}           //无参构造函数
	};         //warning : 'CType' : multiple default constructors specified
	void CType::Set(int n,long m,short s)
	{	this->n=n;this->m=m;this->s=s;	}
	CType::CType(int n,long m,short s)	{   Set(n,m, s)   ;}
	void CType::Show()	  { printf("%d,%d,%d \n",n,m,s);	}
	void main()
	{	  CType* pthis=new CType(1);	//pthis=new CType()导致歧义
		  pthis->Set(7,10,5);    	      pthis->Show();//输出:7,10,5
		  pthis->Set(7,10);    	          pthis->Show();//输出:7,10,5		
		  CType   a(7,10,5);            a.Show();	  //输出:7,10,5	
		  CType   c(7,10);             c.Show();	  //输出:7,10,5	
	}
///////////	[例15.10]编译器默默奉献的成员函数清单
	#include <stdio.h>  
    #include<string.h>   
	class CType
	{   		long m_tData;	
	public:    CType(){}                         //1无参空构造函数 	
		   ~CType(){}                          //2无参空析构函数
		    CType(const CType& r) ;              //3拷贝构造函数
		    CType& operator=(const CType& r);     //4等号运算符函数
	inline   CType* operator&();                  //5取可变对象地址运算符函数
	inline  const	CType* operator&()const;         //6取只读对象地址运算符函数	
	};	 //取只读对象地址运算符函数返回const	CType*型的只读地址值                        
	int  and=0;//设置and变量纪录取地址运算符函数调用情况,and原本是多余的
	CType::CType(const CType& r)     {	memcpy(this,&r,sizeof(CType));	}
	CType& CType::operator=(const CType& r) 
    {	 if(this==&r)  return *this; //函数名为operator=的双目运算符函数
		 memcpy(this,&r,sizeof(CType));
		 return *this; 
	 }                        //函数名为operator&的单目运算符函数
	inline       CType* CType::operator&()	     {and=1;	return this;}
	inline const  CType* CType::operator&() const  {and=2;	return this;}//只读版本
	void main()                                //and=1; and=2;原本是多余的
    {	CType   v;               //定义左值对象v
		CType*  pv=&v;	          //取左值对象地址,调用operator&()
		printf("%d\t", and);	
		const	CType   c;          //定义只读对象c,只读指针pc
		const   CType*  pc=&c;      //取只读对象地址,调用operator&() const
		printf("%d\t", and);	and=0;
		pc=v.operator&() ;            //显式调用名为operator&的取地址运算符函数
		printf("%d\t", and);
	}			//输出:1	2  1







⌨️ 快捷键说明

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