第六章C++类的学习与总结

一、基础知识:
     6.1
     定义格式:
     class 类名
     {
      public:
      公有数据成员和成员函数;
      protected:
      保护数据成员和成员函数;
      private:
      私有数据成员和成员函数;}


      注意事项:
      1、类成员可以为其他类对象
      2、不能以类自身的对象作为本类的成员
      3、类自身的指针和引用可以作为类的成员
      4、以“;”结束类的定义
      
     | 类具有封装性,而结构体没有,因为结构体成员为    公有。


     |类行为属性通过成员函数实现;
     首先将成员函数声明为函数原型,在类外具体定义成    员函数。


     |成员函数的定义模式为:
     返回值类型 类名::成员函数名(参数表)
     {
           函数体
     }
     
     |对象与类关系即为基本数据类型和变量之间的关系,
     先定义类再定义类的对象。


     |可通过原点访问形式(对象名.公有成员)和指针访问形式(对象指针变量名->公有成员)进行类成员的访问。


     |内联函数可减少频繁调用小子程序的运行时间开销;
      其形式为:
      inline 函数原型
      注:内联函数仅在函数原型做一次声明;
             适用于只有1-5行小函数;
             不可含有复杂结构控制语句,不可递归调用


      |函数重载即为函数名相同,而参数不相同(类型不同、个数不同)的函数;
      其用于处理不同数据类型的类似任务。


      |参数个数相同
      类型不同:
        
 int main()
        {cout<<abs(-5)<<endl;
         cout<<abs(-7.8)<<endl;
        }
        int abs(int a)
        {return a<0 ? -a:a;}
        double abs(double f)
        { return abs(double f)
        {return f<0 ? -f:f;}


        
        |参数个数不同:
         
int main()
         {
           cout<<max(5,3)<<endl;
           cout<<max(4,8,2)<<endl;
         }
         int max(int a,int b)
         {
          return a>b?a:b;
         }
         int max(int a,int b,int c)
         {
          int t;
         {
          t=max(a,b);
          return max(t,c);
         }




          6.2 构造函数与析构函数


         |构造函数作用:
          为对象分配空间;
          对数据成员赋初值;
          请求其他成员;
          
         |构造函数名与类名相同;


         |构造函数可以重载;


         |构造函数无返回值,但有各种类型形参;


         |析构函数用于取消对象的成员函数,进行对象消        亡时的清理工作;
        
         |当无用户定义构造函数和析构函数时,系统提供        缺省版本的构造函数和析构函数,缺省的构造函数      为空函数;


         |析构函数无参数也无返回类型;


         |用构造函数创建对象时,通过指针和new来实现         :类名 *指针变量=new 类名(实参表);
          Date *date1=Date(1998,4,28);
          即创建了对象(*date1)


         |构造函数初始化成员俩种方法:
          1、使用构造函数的函数体进行初始化;
          2、使用构造函数的初始化列表进行初始化;
        例1:
             
class Date
            {
	int d, m, y;
            public:
	Date(int dd, int mm, int yy)
	{
		d=dd;
		m=mm;
		y=yy;
	}
	Date(int dd, int mm)
	{
		d=dd;
		m=mm;
	}
               }


           
          例2:


        
            class Date
         {
	int d, m, y;
            public:
	Date(int dd, int mm, int yy):d(dd),m           (mm),y(yy)
	{			}


	Date(int dd, int mm): d(dd),m(mm)
	{               	}
         }



         |类的初始化顺序:
          按照数据成员在类中的声明顺序进行初始化,
         与初始化成员列表中的顺序无关。


         |重载构造函数,构造函数可进行重载,系统将根据参数匹配其中一个。
class Box{
public:
	Box();
	Box(int ,int , int);
	int volume();
private:
	int height,width, length;
};
Box::Box()
{	height=10;	width=10;	length=10;}
Box::Box(int h, int w,int l):height(h),width(w),length(l)
{}
int Box::volume()
{	return width*length*height;}
int main(){
	Box box1;
	cout<<"The volume is "<<box1.volume();
	Box box2(12,30,25);
	cout<<"The volume is "<<box2.volume();
	return 0;
}


       |this指针:
       C++专门设立了一个名为this的指针,用来指向不同   的对象;
       一个对象的this指针不是对象本身的一部分,不会   影响sizeof(对象)的结果;
       以此可区分不同实例对象的数据成员;


       |需要显示引用this指针的情况:
         在类的非静态成员函数中返回类对象本身或                对象的引用的时候,直接使用 return *this,返回本      对象的地址时,return this;
          当参数与成员变量名相同时,如this->x = x,不      能写成x = x;
          避免对同一对象进行赋值操作,判断两个对象是      否相同时,使用this指针;


          |复制构造函数:
           分为深复制与浅复制;


          |浅复制:
           对于复杂类型的数据成员只复制了存储地址而没           有复制存储内容;
           默认复制构造函数为浅复制;

#include <iostream>
#include <string.h>
using namespace std;
class Person 
{
public: 
	Person(char* name1,int a,double s);    
	void display(){cout<<name<<"\t"<<age<<"\t"<<salary<<endl;}
	~Person(){delete name;}		              //析构函数的声明
private:  
	 char* name;
	int age;
	double salary;
};
int main()
{
Person *P1=new Person("WangWei ",8,3880); //调用构造函数创建对象P1
P1->display();
 Person P2(*P1);  //调用复制构造函数,用P1的数据初始化对象P2
	 delete P1;
 P2.display();
return 0;
}


         |深复制:
           通过一个对象初始化另一个对象时,不仅复制了           数据成员,也复制了资源的复制方式为深复制。
           
          |深复制构造函数的特点:
           定义:类名::类名([const]类名 &对象名);
Person::Person(const Person& P0) //复制构造函数的实现
{
   	 name=new char[strlen(P0.name)+1];
	strcpy(name,P0.name);
	age=P0.age;
	salary=P0.salary;
cout<<"ff"<<endl;
} 
         6.3 类的其他成员:
         |常成员(指数据成员在实例化被初始后,其值不能改变)
         |静态成员
         |友元


         |常成员:
 
 
#include<iostream>
using namespace std ;
class  Simple
{   int  x, y ;
  public :
     void setXY ( int a, int b) { x = a ;  y = b ; }
     void printXY() { cout << x << "," << y << endl ; } 
     void  constFun ( ) const
         { x ++ ; y ++ ; }//非法
};

|静态成员:

         类成员冠以static声明时,为静态成员;

         静态成员为同类对象共享;

         静态成员函数与静态数据成员协同操作;

         

         |静态成员函数的作用不是为了对象之间的沟通,而是为了

         能处理静态数据成员,可以在不依赖某个对象的情况下,

         访问静态成员。

          

class A

          {

            int n;

            static int s;

           }

           

           |公有的静态成员的访问形式:

            类名::静态成员的名字;

            对象名.静态成员名字;

            对象指针->静态成员名字;

            静态成员函数内部直接访问;

            |静态数据成员的声明及初始化:

              类外声明

              类型类名::静态数据成员【=初始化值】;

 #include<iostream>

using namespace std ;

class counter

{    static  int  num ;

 public :

     void  setnum ( int i ) { num = i ;}  

     void  shownum() { cout <<num << '\t' ; }

} ;

int counter :: num = 0 ;      

int main ()

{ counter  a , b ;

    a.shownum();    b.shownum() ;

   a.setnum(10) ;

   a.shownum() ;    b.shownum() ;

   cout<<endl ;

}

    |静态成员函数仅可以访问静态成员函数或静态数据成员;

     静态成员的引用不需要用对象名;

     静态成员函数没有this指针;

     |友元函数:
      在类A以外的其他地方定义一个函数(函数B);
      在类体中用friend对函数B声明,函数B即为函数A的友元函数,但A不是B的友元;
      类B可以访问类A的私有数据成员;
      当B为A的友元函数,则B的所有成员函数都为A的友元函数;

      友元函数定义一定要按顺序,当B为A的友元函数,则必须先定义A再定义B;


    样例:

  class  
   { private:
          int  i ;
          friend void FriendFun(A * , int) ; //定义友元函数
      public:
         void MemberFun(int) ;
   } ;
    …
void FriendFun( A * ptr , int x  ) 
     { ptr -> i = x ; } ;  
void A:: MemberFun( int x ) 
     { i = x ; } ;

      6.4 
      |类的包含:
      类的包含是程序设计中一种软件重用技术,
      即定义一个类时,通过编译器把另一个“类”抄进来;
      
      |建立一个类的对象时,要先执行成员对象自己的构       造函数,再执行当前类的构造函数;

      |成员对象的构造函数调用次序和成员对象在类中的      说明次序一致(声明顺序为:a1、b1、b2),与它      们在成员初始化列表中出现的次序无关(初始化            列表顺序为      :b1、b2、a1);

      析构函数的调用顺序相反;
#include<iostream>
      using namespace std;
      class A
      { public:
      A(int x):a(x){ }
   
      int a ;
      }; class B
      { public:
 
      B( int x, int y ) : aa(x)  { b = y ; }
 
      void out()
       { cout<<"aa = "<<aa.a<<endl<<"b = "<<b<<endl ; }
       private:
    
       int b ;
   
       A aa ;	
} ;
       int main()
              
       { B objB( 3, 5 ) ;
       objB.out();}
       |对象数组是指每一数组元素都是对象的数组;
       定义一个一维对象数组的格式:
       类名 数组名【下标表达式】;
          
       |当对象数组所属的类中包含无参的构造函数,也可以先定义,再给每个数组元素赋值;

       |创建对象数组时使用构造函数,删除对象数组时使用析构函数;
 
 

    二、总结及心得:

     类作为自定义数据类型,具有封装性、继承性、多态性的特点,构造函数对数据进行初始,析构函数对数据进行删除的功能。其应用将主函数内容简化,将程序分为多个模块,无疑有利于书写长篇幅的系统,书写系统时应该分模块进行调节,虽然相比于C语言而言,其看似更繁,但可使我们转换思维方式,使我们拥有了“设计”的概念,类这一部分的学习对于本人这样初次接触的小白来说,无疑难如上青天,自知目前对类的认识不够深刻,虽然学习途中困难重重,但我觉不会轻言放弃的!


猜你喜欢

转载自blog.csdn.net/MYSOUL147/article/details/80081721