类与对象总结

一.知识点

1.类

class<类名>   //类名的首字母大写

{public:

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

private:

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

}

注:(1)c++默认类class成员的访问为私有private,struct的为public

    (2)数据成员私有化,成员函数公有化

    (3)先考虑如何组织数据,再解决问题。首先定义类,再写主函数(程序从主函数开始运行) 主函数中包括对象的定义说明,对象只能通过成员使用,对象.公有成员

 

2.成员函数

⑴成员函数在类外定义形式    返回类型 类名::函数名(参数表)

一般在类外具体实现成员函数

例如:voidDate::SetDate(int y,int m,int d)

{ year=y;

month=m;

day=d;}

⑵简单成员函数也可以在类内定义

例如:void SetDate(int y,int m,int d)

{year=y;

month=m;

day=d;}

注:⑴在类的定义中不能对数据成员初始化

    ⑵类的组合:一个类的成员可以是已经定义的其他类的对象,可以是数组、类等

3.对象

⑴定义:对象是类的实例或实体,类与对象的关系,如同C++基本数据类型和该类型的变量之间的关系。

(2)格式:类名  对象名1,对象名2,…,对象名n;

(3)类对象的访问

       圆点访问形式:对象名.公有成员名

       指针访问形式:对象指针变量名->公有成员名

注:必须在定义了类之后,才可以定义类的对象。

4.this指针

this指针在类内使用,指明对象本身

类的成员函数如何区分不同的实例对象的数据成员?

    C++为此专门设立了一个名为this的指针,用来指向不同的对象。

    一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果。

需要显式引用this指针的三种情况

(1)在类的非静态成员函数中返回类对象本身或对象的引用的时候,直接使用 return *this,返回本对象的地址时,return this。

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

(3)避免对同一对象进行赋值操作,判断两个对象是否相同时,使用this指针。

 

例如:voidTclass::print()

{cout<<this->x<“  ”<<this->y<<endl;

5.函数重载

函数名相同,但参数不相同(类型不同,或者个数不同)的一组函数。

编译器根据不同参数的类型和个数产生调用匹配

函数重载用于处理不同数据类型的类似任务

例如:参数的个数不同

class Date

{public:

Date();

Date(int):

Date(int,int);

};

void f()

{Date d;//调用Date()

Date d1(2000);调用Date(int)

Date d1(2000,1);调用Date(int int)

}

6.构造函数与析构函数(重点)

构造函数与析构函数是类的特殊成员函数,应定义在公有部分

(1)构造函数名与类名相同,可以有任意类型的参数,但不能有返回类型,为对象分配空间;对数据成员赋初值;请求其他资源  构造函数可以重载

析构函数是在类名之前加 ~  无参数没有返回类型  自动调用 释放对象释放空间,一个类中只能有一个析构函数;

 

(2)构造函数形式:类名::类名(参数表);

析构函数形式:类名::~类名();

(3)没有用户定义的构造函数时,系统提供缺省的构造函数

调用对应构造函数后,用户定义了构造函数后,缺省构造函数不再起作用,所以必须先定义不带参的构造函数

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

 

(5)利用构造函数创建对象有以下两种方法:

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

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

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

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

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

new 动态申请空间申请后返回首地址 所以定一个指针变量

例如:

      Date *date1=new Date(1998,4,28);

date1->showDate();

就创建了对象(*date1)

(6)构造函数的初始化列表(数据成员的初始化)

构造函数初始化成员有两种方法
 
A.
使用构造函数的函数体进行初始化

B.使用构造函数的初始化列表进行初始化 

必须用参数初始化列表对数据成员进行初始化的几种情况

①数据成员为常量

②数据成员为引用类型

③数据成员为没有无参构造函数的类的对象

(7复制构造函数

复制构造函数有一个类类型的引用参数,用一个已有同类对象创建新对象进行数据初始化,C++为类提供默认版本的复制构造函数  包括深复制与浅复制,深复制用new申请空间

语法形式

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

注:(1)这里用const 保护实参对象为只读,保证所引用对象不被修改

(2)深复制构造函数必须显式定义,特点

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

②   成员变量的处理:对复杂类型的成员变量,使用new操作符进行空间的申请,然后进行相关的复制操作

 

 

复制构造函数的特点:

①    复制构造函数名与类名相同,并且也没有返回值类型。

②     复制构造函数可写在类中,也可以写在类外。

③     复制构造函数要求有一个类类型的引用参数。

④     如果没有显式定义复制构造函数,系统自动生成一个默认形式的复制构造函数。

注:(1)构造函数Date::Date()与成员函数Date::SetDate()作用不同,通过SetDate,可以多次重置数据成员的值,但构造函数不能通过对象显式调用首先创建的对象最后析构

(2)对象不要定义成全局对象,不能定义在主函数之外

7.类成员的初始化的顺序:

按照数据成员在类中的声明顺序进行初始化,与初始化成员列表中出现的顺序无关,成员对象的构造函数调用次序和成员对象在类中的说明次序一致(声明顺序为:a1b1、b2),与它们在成员初始化列表中出现的次序无关(初始化列表顺序为:b1、b2a1)即析构函数的调用顺序相反

 

例如:

#include <iostream>

using namespace std;

class CmyClass

{

public:

   CMyClass(int x, int y):m_y(x),m_x(m_y)

   {

      cout<<"m_x="<<m_x<<endl;

      cout<<"m_y="<<m_y<<endl;

   }

private:

   int m_x,m_y;

};

int main()

{

   CMyClass mc(15,10);

   return 0;

}

运行结果

m_x=-858993460

m_y=15

 

 

8.类的其他成员

(1常成员只读不写)用关键字const,c

常数据成员构造函数只能通过初始化列表对常数据成员进行初始化,初始化列表形式类名():数据成员(形参){赋值语句},使用const说明的数据成员称为常数据成员,const放在前面。

        如果在一个类中说明了常数据成员,那么构造函数就只能通过初始化列表对该数据成员进行初始化,而任何其他函数都不能对该成员赋值。

 

例如:

由构造函数直接用常量初始化常数据成员

#include<iostream>

using namespace std;

class Mclass

{ public :

       int k;

       const int M;//说明常数据成员

       Mclass() : M(5) { } //用初始式对常数据成员赋值

       void testFun()

        { //M++;

            k++;

        }

 } ;

(2)常对象

①常对象的说明形式如下:

      类名const 对象名[(参数表)];

  或者

      const 类名 对象名[(参数表)];

②在定义常对象时必须进行初始化,而且不能被更新。

 (1)C++不允许直接或间接更改常对象的数据成员。

 (2)C++规定常对象只能调用它的常成员函数、静态成员函数、构造函数(具有公有访问权限)

(3)常成员函数

常成员函数的形式  类型说明符 函数名(参数表) const;

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

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

 

9.静态成员(static

即类成员,不属于某个单独的对象,而是为类的所有对象所共有

(1)静态数据成员

①静态数据成员的说明

在定义或说明时前面加关键字static

如:

class A

{

    int n;

    static int s;

};

②静态数据成员的初始化   直接说明类以后赋初值,不能在初始化列表中赋值

③静态数据成员的访问

公有访问权限的静态成员,可以通过下面的形式进行访问

访问形式 类名::静态成员的名字

对象名.静态成员名字

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

在静态成员函数内部,直接访问。

注:①在类说明中,静态数据成员的声明不是定义,因此必须在类外定义

    ②类定义完后,对静态成员赋初值形式 (在类外对静态成员函数赋初值)

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

③不能在成员初始化列表中进行初始化

如果未进行初始化,则编译器自动赋初值(默认值是0

 

 

(2静态成员函数

仅可以访问静态成员、静态成员函数、静态数据成员,对静态成员的引用不需要用对象名。

静态成员函数没有this指针,只能对静态数据操作

定义静态成员函数的格式:

    static 返回类型 静态成员函数名(参数表);

调用公有静态成员函数的格式:

   类名::静态成员函数名(实参表)

   对象. 静态成员函数名(实参表)

   对象指针->静态成员函数名(实参表)

注:(1)静态成员函数在类外定义时不用static前缀。

(2)静态成员函数主要用来访问同一类中的静态数据成员。

(3)私有静态成员函数不能在类外部或用对象访问。

(4)成员函数中是没有this指针的。

(5)成员函数不访问类中的非静态数据成员。如有需要,只能通过对象名(或指向对象的指针)访问该对象的非静态成员。

 

10.友元函数(friend

在类中,friend放在函数原型或类名之前

 

11.类的包含

定义一个新的类时,把另一个类 “抄”进来,即 一个类的数据成员中包含另一个类的对象

 当一个类中含有已经定义的类类型成员,带参数的构造函数对数据成员初始化,须使用初始化语法形式。

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

注:(1出现成员对象时,该类的构造函数要包含对象成员的初始化。如果构造函数的成员初始化列表没有对成员对象初始化时,则使用成员对象的无参(缺省构造函数。

(2)建立一个类的对象时,要先执行成员对象自己的构造函数,再执行当前类的构造函数。

有关简单对象成员初始化的问题

如何对数据成员进行初始化?
构造函数的作用
构造函数定义特点。
名字?
返回值?
参数
默认的构造函数
构造函数的重载
初始化成员列表

 

例如:

#include<iostream>

using namespace std;

class A

{ public:

     A(intx):a(x){ }

     int a;

};

class B

{ public:

     B( intx, int y ) : aa(x)  { b = y ; }

     voidout() { cout<<"aa = "<<aa.a<<endl<<"b ="<<b<<endl ; }

  private:

     int b;

     A aa ; 

} ;

int main()

{ B objB( 3, 5 ) ;

 objB.out() ;

}

 

二.简单例题

1.成员初始化列表与无参构造函数的使用

#include<iostream>

using namespace std;

class A{

public:

   A( ){cout<<"This is A."<<endl; }      //缺省构造函数

   A(int i){ cout<<"This is A, and it's value = "<<i<<endl; }

};

class B{ 

public:

   B( ){  cout<<"This isB"<<endl;   } //缺省构造函数

   B(inti):a2(i) { cout<<"Hello B!"<<endl;m} //采用成员初始化列表的方式,成员对象a1的形参未初始化,将成员对象a2的形参初始化为i

private:

   Aa1,a2;  //声明两个A类对象a1和a2

};

int main( )

{

   B b1,b2(9);  

   return 0;

}

 

2.  简单的学生信息管理系统

在学生信息管理的过程中, 需要知道每个学生的姓名,学号以及考试成绩

①   可以定义一个学生类,数据成员包括name(string), number(string)

②   考试科目比较多

(1)  方法一:在类中增加新的数据成员

(2)  方法二,定义成绩类,采用类的组合解决问题

class Score

{

public:

    Score(float c, float e, float m );

    Score();

    void show();

    void modify(float c, float e, float m);

private:

    float computer;

    float english;

    float mathematics;

};

class Student

{

private:

    string name;

    string stu_no;

    Score score1;

public:

    Student(string name1, string stu_no1, floats1, float s2, float s3):score1(s1,s2,s3){

        name=name1;

         stu_no=stu_no1;

}

~Student();

    void modify(string name1, char *stu_no1,float s1, float s2, float s3);

    void show();

};

void main()

{

    Student stu1("LiMing","990201", 90, 80, 70);

    stu1.show ();

    cout<<endl;

    stu1.modify ("ZhangHao","990202", 95, 85, 75);

    stu1.show ();

}


该程序只能处理一个学生的信息。

显然,考试管理要管理若干学生的信息。

利用对象数组解决问题

Student stu[100];这是定义一个对象数组,对象数组形式  类名 数组名[下标表达式];

(1)  定义一个Student

      该类对象所共有的属性

      姓名,学号,数学成绩,英语成绩,计算机,平均成绩,学生名次

      该类对象的操作

      初始化一个对象(输入一个学生的相关信息)

      输出每个对象的信息

      修改信息

(2)      定义一个成绩表类

     一个数据成员,记录班级人数

     一个对象数组,记录所有同学的信息

      该类的操作

      构造函数,输入学生人数,并输入相应的学生信息

      追加函数:补充学生信息到对象数组中,并增加学生人数;

      查询:按照学生的学号进行信息的查询

      修改:按照学生的学号进行信息的修改

      删除某个学生:删除某个数组分量,同时学生人数减1

      统计每个分数段的学生的人数

(3)      设计操作类

     一个成员函数实现一个具体功能;

      设确定数据成员,设计构造函数;

(4)    设计数据类

      整合操作类所需要的数据、设计数据类

      明确如何修饰数据成员、确定数据类的成员函数

 (5)     编码调试数据类

      在main函数中创建数据类对象、调用各成员函数

 (6)  调试操作类

      先调试最急需的成员函数;

      再陆续增加成员函数

      最后增加菜单函数

      调试方法同数据类

      设计多组测试数据,用不同的测试数据反复运行程序

注:管理信息系统开发基本步骤

     了解系统要实现什么功能?增删查改

      对系统功能进行分类汇总


三.心得体会

        这一章学习了类和对象的有关知识,对如何开发和调试系统有了初步的皮毛的了解,先考虑如何组织数据,然后再解决问题,做系统主要分为两大部分写程序和调程序。程序主要分为两大类,数据类与操作类,数据类用于描述信息,在成员函数中肯定至少有一组get()set()函数和构造函数。操作类用于实现程序的具体功能,例如管理信息系统主要有“增删查改”四个功能。操作类中一定有数据成员,并且数据成员一定是集合类型即对象数组。调试程序用“滚雪球法”,将实际问题分解成若干个小问题,先想操作,再想数据,每定义一个类,先将他调通,再写下面的程序。

        但是总是感觉最近学的迷迷糊糊的,有些概念不清楚,有些概念总是混在一起分不清,有的使用形式不清楚,总而言之,不大会定义类,写类时只能比着书上的例题或已经给出的程序敲,在定义对象后,怎么在主函数中调用类还是有点疑问,如何解决问题,这个系统要实现什么功能,怎么一步步地用代码实现功能,如何调用数据,怎么将一个个的小类最后整合在一起,完成一个系统,这些问题有的似懂非懂,有的懂了但不会运用。以前c++有不大懂的问题时还可以去问同学或者百度,但现在有的时候自己连问题都不知道怎么去描述,自己具体是哪里不明白也说不上来,怎么去学好类也不懂得方法,总而言之,最近这一章学的比较吃力,学的也不大扎实,心里有点怕。

 

 

 

 

 

 

 

 

 

 

 

 

 

 



 

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值