类与对象学习总结

类和对象的定义与访问

1、定义类和对象

C++中,类定义的说明语句一般形式为:

class<类名>

{

  public:

         公有段数据成员和成员函数;

  protected:

         保护段数据成员和成员函数;

  private:

         私有段数据成员和成员函数;

};

其中,class是定义类的关键字。“类名”是用户自定义的标识符,用于标识类型的名字。一对花括号相括说明类的成员,以分号结束类定义语句。

*注:

 类成员用关键字指定不同的访问特性,决定其在类体系中或类外的可见性。

 private用于声明私有成员。私有成员只能在类中可见,不能在类外或派生类中使用。

 protected声明保护成员。保护成员在类和它的派生类中可见。

 public声明公有成员。公有成员是类的接口,在类中和类外可见。

例:一个日期类的说明

class Date
{
   public:
      void SetDate(int y,int m,int d);
      int IsLeapYear();
      void PrintDate();
   private:
      int year,month,day;
};

2、访问对象成员

对象成员的访问形式与访问结构的形式相同,运算符“.”和“->”用于访问对象成员。

例:访问对象的公有成员

#include<iostream>
using namespace std;
class Tclass
{  public:
      int x,y;
      void print()
      {   cout<<x<<","<<y;   };
};
int main()
{   Tclass test;
    test.x=100;   //访问公有段数据成员
    test.y=200;
    test.print(); //调用公有段成员函数
}

3、this指针

一般来说,所有类方法都将this指针设置为调用它的对象的地址;

当参数与成员变量名相同时,如this->x = x,不能写成x = x。

构造函数和析构函数

1、构造函数

如果类中没有定义构造函数,系统将自动生成一个默认形式的构造函数,用于创建对象,默认构造函数形式:  

类名::类名(){} 

默认构造函数是一个空函数。

*注:

构造函数可以重载。
构造函数可以有任意类型的参数,但 没有 返回类型。
通常,利用构造函数创建对象有以下两种方法:

(1) 利用构造函数直接创建对象.其一般形式为:

             类名 对象名[(实参表)];

          这里的“类名”与构造函数名相同,“实参表”是为构造函数提供的实际参数。 

(2)利用构造函数创建对象时,通过指针和new来实现。其一般语法形式为:

      类名 *指针变量 = new 类名[(实参表)];

例:为类Date建立一个构造函数。

#include <iostream.h>
class Date {
    public:
	    Date();     // 无参构造函数
	    Date(int y,int m,int d); 
	    void showDate();
    private:
            int year, month, day;
    };
Date::Date()    // 构造函数的实现
{  year=0; month=0; day=0; }
Date::Date(int y,int m,int d) 
{ year=y; month=m; day=d; }
inline void Date::showDate()
{  cout<<year<<"."<<month<<"."<<day<<endl; } 
int main()
{
     Date a_date,bDate(2014,3,25);   
     a_date.showDate();
     b_date.showDate();
     return 0;
}
2、析构函数
析构函数的 定义格式如下 ( 类外实现 ) : 

类名::~类名()

{

      函数语句

}

若没有显式定义析构函数,则系统自动生成一个默认形式的析构函数。

系统自动生成的默认构造函数形式如下: 

类名 ::~ 类名 (){}

一般情况下,可以不定义析构函数

但如果类的数据成员中包含指针变量是从堆上进行存储空间分配的话,需要在析构函数中进行存储空间的回收

*注:

析构函数与构造函数名字相同,但它前面必须加一个波浪号(~)。

析构函数没有参数,也没有返回值,而且不能重载。因此在一个类中只能有一个析构函数。

当撤消对象时,编译系统会自动地调用析构函数。 

复制构造函数

复制构造函数用一个已有同类对象创建新对象进行数据初始化

C++为类提供默认版本的复制构造函数

程序员可以定义用户版本的复制构造函数

 语法形式

 类名::类名(const  类名  & 引用名 ,  …);

*注:

复制构造函数名与类名相同,并且也没有返回值类型。
复制构造函数可写在类中,也可以写在类外。
复制构造函数要求有一个类类型的引用参数。
如果没有显式定义复制构造函数,系统自动生成一个默认形式的复制构造函数。 

例:复制构造函数的基本工作

class Point	
{
public:	 
      Point(float PointA_x=0, float PointA_y=0); 
void Move(float New_x, float New_y);
float GetPointx();
float GetPointy();
private:
   float P1_x,P1_y;
};

浅复制

用一个对象初始化另一个对象时,只复制了数据成员,而没有复制资源,使两个对象同时指向了同一资源的复制方式称为浅复制。

即:对于复杂类型的数据成员只复制了存储地址而没有复制存储内容。

默认复制构造函数所进行的是简单数据复制。

深复制

通过一个对象初始化另一个对象时,不仅复制了数据成员,也复制了资源的复制方式称为深复制。 

定义:

类名::类名([const]类名 &对象名);

类的其他成员

常成员

常数据成员是指数据成员在实例化被初始化后 , 其值不能改变。
在类的成员函数说明后面可以加 const 关键字,则该成员函数成为常量成员函数。

在类中使用关键字const说明的函数为常成员函数,常成员函数的说明格式如下:

类型说明符函数名(参数表) const;

const是函数类型的一个组成部分,因此在函数的实现部分也要带关键字const。

常成员函数不能更新对象的数据,也不能调用非const修饰的成员函数(静态成员函数、构造函数除外)。

例:由构造函数直接用常量初始化常数据成员
#include<iostream>
using namespace std;
class Mclass
{ public :
       int k;
       const int M;
       Mclass() : M(5) { } 
       void testFun()
        { //M++;
            k++;
        }
 } ;

静态成员

类成员冠以 static 声明时,称为静态成员,为同类对象共享,与静态数据成员协同操作。  

静态数据成员在定义或说明时前面加关键字static,如:

class A

{

   int n;

  staticints;

};

*注:

静态成员不属于某一个单独的对象,而是为类的所有对象所共有。
静态成员函数的作用不是为了对象之间的沟通,而是为了能处理静态数据成员:保证在不依赖于某个对象的情况下,访问静态数据成员。

友元

如果在本类(类A)以外的其他地方定义了一个函数(函数B)
这个函数可以是不属于任何类的非成员函数,
也可以是其他类的成员函数,
在类体中用friend对其(函数B)进行声明,此函数就称为本类(类A)的友元函数。
友元函数(函数B)可以访问这个类(类A)中的私有成员
类的包含

构造函数 ( 形参表 ) : 对象成员1(形参表 ) , … , 对象成员n (形参表 ) ;

例:

class  A  
   { 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 ; } ;  

附:学生成绩查询

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
class student
{
    string name;
    int no;
    int score[3];
    float average;
    int order;
    public:
    student(int id,string na,int x,int y,int z):name(na),no(id)
    {
    score[0]=x;
    score[1]=y;
    score[2]=z;
    order=1,average=(score[0]+score[1]+score[2])/3;
    }
    student()
    {
        score[0]=score[1]=score[2]=0;
        order=1,average=0;
    }
    int getNo(){return no;}
    float getAverage(){return average;}
    void setAverage(int avg){average=avg;}
    void setOrder(int x){order=x;}
    int getOrder(){return order;}
    string getName(){return name;}
    void setName(string name){this->name=name;}
    void display();
};
void student::display()
{
    cout<<name<<"\t"<<no<<"\t"<<score[0]<<"\t"<<score[1]<<"\t"<<score[2]<<"\t"<<average<<"\t"<<order<<endl;
}
bool cmp1(student stu1,student stu2)
{
    if(stu1.getAverage()-stu2.getAverage()>=1e-9)return 1;
    else return 0;
}
bool cmp2(student stu1,student stu2)
{
    return stu1.getNo()<stu2.getNo();
}
class student_list
{
    student list[60];
    int n;
    public:
    student_list():n(0){};
    void add();
    void deleteStu();
    void query();
    void change();
    void display(int flag);
    void menu();
    int search(int no);
    void sortList();
};
void student_list::add()
{
    int no,x,y,z;
    string name;
    system("cls");
    cout<<"按学号·姓名·数学·英语·c++顺序输入学生信息,学号输入-1表示结束"<<endl;
    while((cin>>no)&&no!=-1)
    {
        cin>>name>>x>>y>>z;
        student s(no,name,x,y,z);
        list[n++]=s;
        sortList();
    }
}
void student_list::sortList()
{
    sort(list,list+n,cmp1);
    int i;
    for(i=0;i<n;i++)
    list[i].setOrder(i+1);
}
void student_list::display(int flag)
{
    if(flag)sort(list,list+n,cmp2);
    else sort(list,list+n,cmp1);
    cout<<"姓名"<<"\t"<<"学号"<<"\t"<<"数学"<<"\t"<<"英语"<<"\t"<<"c++"<<"\t"<<"平均成绩"<<"\t"<<"名次"<<endl;
    for(int i=0;i<n;i++)
    list[i].display();
}
int student_list::search(int no)
{
    int i;
    for(i=0;i,n;i++)
    if(list[i].getNo()==no)
    return -1;
}
void student_list::query()
{
    int no,i;
    system("cls");
    cout<<"请输入要查询同学的学号,按-1结束查询";
    while(cin>>no&&no!=-1)
    {
        i=search(no);
        if(i!=-1)
        {
            cout<<"姓名"<<"\t"<<"学号"<<"\t"<<"数学"<<"\t"<<"英语"<<"\t"<<"c++"<<"\t"<<"平均成绩"<<"\t"<<"名次"<<endl;
            list[i].display();
            cout<<"请输入要查询同学的学号,按-1结束查询";
        }
        else
        cout<<"学号输入有误,请重输,输入-1结束查询"<<endl;
    }
}
void student_list::change()
{
 int no,i,x,y,z;
 string name;
 system("cls");
 cout<<"输入要修改的学生学号,按-1结束查询"<<endl;
while(cin>>no&&no!=-1)
 {
     i=search(no);
     if(i!=0)
     {
         cout<<"修改后的同学的姓名·数学·英语·c++"<<endl;
         cin>>name>>x>>y>>z;
         student s(no,name,x,y,z);
         list[i]=s;
         sortList();
         cout<<"请输入要修改同学的学号,按-1结束查询"<<endl;
     }
     else
     cout<<"学号输入有误,请重输,输入-1结束查询"<<endl;

 }
}
void student_list::deleteStu()
{
    int no;
    system("cls");
    cout<<"请输入要删除同学的学号,按-1结束查询";





}
int main()
{
    student s(1,"ff",66,77,88);
    s.display();
    cout<<s.getAverage()<<endl;
    s.setName("方法");
    s.display();
    student_list c;
    c.add();
    c.display(1);
    c.query();
    c.display(0);
    c.change();
    c.deleteStu();
    return 0;


}

总结:

通过这一章的学习,完成了由面向过程到面向对象的思维转变。同时也让我对设计管理系统有了一个初步的理解,即先了解所需求的功能,然后设计框架,进行分类以及接下来的数据修饰。但随着课程的逐步深入,我也感觉到了C++学习的越发困难,但我会继续努力。







  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值