计算机等级考试二级C++考点分析之类和对象

来源:百度文库 编辑:神马文学网 时间:2024/04/28 15:46:44

6.1 类的定义

考点1 类的定义

  C++语言的类是一种用户自己定义的数据类型,和其他的数据类型不同的地方是组成这种类型的不仅可以有数据还可以有对数据进行操作的函数,它们分别叫做类的数据成员和类的函数成员。类是面向对象程序设计的核心,数据封装就是通过类来实现的。
  类是对一组性质相同对象的描述。类的定义形式一般分为说明部分和实现部分。说明部分是用来说明该类中的成员,实现部分是用来对成员函数的定义。类的一般定义形式为:
  class<类名>
  {
     private:
     <私有的数据和函数>
     public:
     <公有的数据和函数>
     protected:
     <保护的数据和函数>
 };
     <各个成员函数的实现>
  其中,类定义以关键字class开始,其后跟类名,类名必须是一个有效的C++标识符。
  类所说明的内容用花括号括起来,右花括号后的分号的作用是类说明语句的结束标志。“{}”之间的内容称为类体。关键字private,public和protected称为访问权限修饰符或访问控制修饰符,它们用于限制类成员的控制访问范围,如果没有使用多,则所有成员默认定义为private权限。这些关键字的声明顺序和次数都是任意的。<各个成员函数的实现>是类定义中的实现部分,这部分包含所有在类体内说明的成员函数的定义。各个成员函数的实体内类体内定义,又可以在类体外定义。如果一个成员函数在类体内定义,实现部分将不出现;如果所有的成员数都在类体内定义,则实现部分可以省略在类体内定义的成员函数都是内联函数。

 小提示:
   C++规定任何数据类型都必须先定义后使用,类也不例外。

考点2 类成员的访问控制

  类成员均具有一个属性,叫做访问控制权限。所以从访问权限上来讲,类的成员又分为私有的(private),公有的(public)和保护的( protected) 3类。公有成员定义了类的外部接口,只有公有成员才能被用户程序直接访问;私有成员定义了类的内部使用的数据和函数,私有成员只能被自己所属类的成员函数及友元函数访问;保护成员存取权限介于公有成员和私有成员之间,它在类的继承和派生中使用。

小提示:
  一个类可以没有私有成员,但是不能没有公有成员。

考点3 类的数据成员和类的函数成员

  1.类的数据成员
  数据成员是类的一个重要组成部分,它描述了对象的内部数据结构。类的数据成员是类的基础,应该正确、完整地定义类的数据成员。定义类的数据成员应注意:
  (1)在类体中不允许对所定义的数据成员进行初始化。
  (2)类中的数据成员的类型可以是任意的,包含整型、浮点型、字符型、数组、  指针和引用等,也可以是对象。另一个类的对象可以作为该类的成员,但是自身类的对象是不可以的,而自身类的指针或引用则是可以的。当一个类的对象作为这个类的成员时,如果另一个类的定义在后,则需要提前说明。
  2.类的函数成员
  函数成员实现对类中数据成员的操作,它描述了类的行为。由于对象的封装性,类的函数成员是对类的私有数据成员进行操作的惟一途径。类中所有的函数成员都必须在类体中说明,但函数成员的定义既可在类体内,也可在类体外。
  (1)在类体内直接给出函数的定义。例如,下面是在类体内给出类成员函数实现的例子:
       class Shijian{
          private:
             int Shi,Fen,Miao;
          public:
             void Set(int S, int F, int M)//可省略此成员函数的变量标识符
        {Shi=S;
             Fen=F;
             Miao=M;}
        void Display(){
             cout<<"现在时间是:";
             cout<            }
        };
  (2)在类体外给出函数的定义。定义形式如下:
     <返回类型><类名>::<成员函数名>(<参数表>)
     {<成员函数体>}
  成员函数定义的结构与普通函数不同之处是在返回类型和函数名之间加了一个类名和双冒号“::”。::是作用域运算符,用来标识成员函数或数据成员是属于哪个类的实理成员函数时参数表中的形参变量标识符可以省略。例如,实现上例中的成员函数Diaplay():
  void Shijian::Disptay()
  {cout<<"现在时间是:";
     cout<  另外,类成员函数同普通函数一样,也可以进行重载及其默认参数。

小提示:
  类的每个成员函数在说明中最后的分号不可省略,但在类体内实现时省略分号。

6.2 对象的定义

考点4 对象的定义

  类名仅提供该类的类型定义,只有在定义属于类的变量后,系统才会在内存预留空间。
  对象是类的实例,是由类作为类型定义的变量。定义对象之前一定要先说明该对象的类。定义一个对象同定义一个变量类似,其语法形式为:
        <类名><对象名表>(<参数表>);
  其中,<对象名表>中可以有一个或多个对象名,有多个对象名时用逗号分隔。<对象名表>中还可以是指向对象的指针名或引用名,也可以是对象数组名。<参数表>是进行初始化对象时需要的。

考点5 对象的成员
  用类定义了对象以后,对象就具有了类的所有性质。也就是说一个对象成员包含了该对象的类所定义的所有数据成员和函数成员。访问一般对象和引用对象可以用"."运算符;访问指针对象可以用->。一般对象的数据成员表示形式为:
        <对象名>.<成员名>
  一般对象的函数成员表示形式为:
        <对象名><成员名>(<参数表>)
  指向对象的指针的成员表示形式为:
        <对象指针名>一><成员名>(表示数据成员)
  上述形式也可写成:(*<对象指针名>).<成员名>
     <对象指针名>一><成员名>(<参数表>)(表示函数成员)

6.3 构造函数与析构函数

考点6 构造函数和析构函数的定义

  构造函数和析构函数是在类体中说明的两种特殊的成员函数。构造函数的功能是在创建对象时利用特定的值构造对象,将对象初始化为一个特定的状态,使此对象具有区别于其他对象的特征。析构函数的功能是用来释放一个对象,在对象删除前,用它来做一些清理工作,与构造函数的功能正好相反。构造函数和析构函数都没有返回值,并且定义它们时不需要显式地写出没有返回值。构造函数可以带参数,也可以重载;而析构函数不能有参数,也不能重载。
  构造函数的特点:
  (1)构造函数是特殊的成员函数,函数体可以写在类体内,也可以写在类体外。该函数的名字与类名相同,该函数不能指定返回类型。
  (2)构造函数一般都被声明为公有函数。构造函数可以重载,即可以定义多个参数个数不同或参数类型不同的构造函数。
  (3)构造函数在定义对象时被系统直接调用,程序中不能直接调用构造函数。
  (4)应用构造函数定义对象的语法形式为:
      <类名><对象名>(<构造函数的参数表>);
  (5)运算符new和构造函数一起使用。
  析构函数的特点:
  (1) 析构函数是特殊的成员函数,函数体可以写在类体内,也可写在类体外。该函数的名字为求反符号“~”后面跟着类名,该函数不能指定返回类型,不能有参数,也不能重载。
  (2)一个类只能定义一个析构函数。
  (3)析构函数在对象生命周期结束时被系统直接调用,程序中一般不调用析构函数。
  (4)运算符delete与析构函数一起使用。

考点7 默认构造函数和默认析构函数

  1.默认构造函数
  不带参数的构造函数又称为默认构造函数,当没有为一个类定义任何构造函数的情况下,C++编译器总要自动建立一个不带参数的构造函数。它的定义形式为:
          <类名>::<类名>()
        {
  }
  即它的函数体是空的。默认构造函数的函数名与类名相同,它的参数表或为空或所有的参数都有默认值。
  2默认析构函数
  每个对象都有一个析构函数,如果在定义一个类时没有定义一个析构函数,C++编译器要为这个类产生一个默认的析构函数。它的定义形式为:
        <类名>::<类名>()
        {
  }
    函数体也是空的。

考点8 拷贝(复制)构造函数

  拷贝构造函数是一个特殊的构造函数,具有一般构造函数的所有特性,它只有一个参数,参数类型是本类对象的引用。它的功能是用一个已知的对象来初始化一个被创建的同类的对象。拷贝构造函数的一般形式为:
    <类名>::<拷贝构造函数名>(const<类名>&<引用对象名>)
    {//拷贝构造函数体}
  其中,<拷贝构造函数名>与类名相同,因为拷贝构造函数也是一种构造函数。拷
贝构造函数也不被指定返回类型。每一个类都必须有一个拷贝构造函数。如果类中没有声明拷贝构造函数,则编译系统自动生成一个具有上述形式的公有的拷贝构造函数,作为该类的公有成员。
  普通构造函数只在对象创建时被自动调用,而拷贝构造函数可以在下面3种情况下被自动调用。
   (l)用类的已知对象定义该类的一个正在被创建的对象。
   (2)对象作为函数的实参传递给函数形参
   (3)对象作为函数返回值。

6.4 对象的生存周期

考点9 全局对象、静态对象与局部对象

  对象从被创建开始到被释放为止的这段时间称为对象的生存周期。根据对象的生存周期可将对象分为3类。
  (1)全局对象。全局对象的作用域最大,生存周期最长。调用构造函数创建该对象的时间是当程序开始执行时;调用析构函数释放该对象的时间是当程序结束时。
  (2) 静态对象。静态对象的作用域和生存周期处在全局对象和局部对象之间。调用构造函数创建该对象时间是当程序第一次执行到该对象的定义之处时;调用析构函数释放该对象的时间是当程序结束时。
  (3)局部对象。局部对象的作用域最小,生存周期最短。调用构造函数创建该对象的时间是当程序执行到该对象的定义之处时;调用析构函数释放该对象的时间是当程序退出定义该对象听在的函数体或程序块时。

考点10 自由存储对象
  所谓自由存储对象是指在程序运行过程中根据需要可以随时建立或删除的对象由堆运算符new和delete 来完成建立和删除的工作。自由存储对象在调用构造函数和析构函数时需要注意的是:此时的调用是显示地进行,调用顺序取决于new和delete运算符的顺序。
 
6.5  this指针

考点11 this指针的使用

  C++规定,this指针是隐含在对象成员函数内的一种指针。当一个对象被创建后,它的每一个成员函数都含有一个系统自动生成的隐含指针――this,用以保存这个对象的地址。因此this也称为“指向本对象的指针”,它存取类成员变量的格式为:
        this-><成员变量>
   this指针是C++实现封装的一种机制,它将对象和该对象调用的成员函数连接在一起,在外部看来,每一个对象都拥有自己的函数成员。一般情况下,并不写this,而是让系统进行默认设置。

小提示:
  this指针永远指向当前对象。

6. 6 静态成员和常成员

考点12 静态数据成员

  如果类的数据成员或成员函数使用关键字static进行修饰,这样的成员称为静态数据成员或静态成员函数。静态数据成员是类的所有对象的共享成员,而不是某个对象的成员。静态数据成员的值对每个对象都是一样的,但它的值是可以更新的。静态数据成员的使用方法和注意事项如下:
  (l)静态数据成员在定义或说明时前面加关键字static o
  (2)静态数据成员必须进行初始化,而且它的初始化与一般的数据成员初始化不同。它的初始化格式为:
            <数据类型><类名>::<静态数据成员名>=<值>;
  从而可知:初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆;初始化时不加该成员的访问权限控制符;初始化时使用作用域运算符来标明它所属的类,所以,静态数据成员是类的成员,而不是对象的成员。
  (3)如果静态数据成员的访问权限允许的话(即为public成员),可在程序中按下面形式来引用静态数据成员。形式为:
            <类名>::<静态数据成员>

考点13 静态成员函数

  静态成员函数与静态数据成员一样,都属于类的静态成员,它们都不是对象的成员。所以,对静态成员的引用不需要用对象名。在静态成员函数的实现中不能直接引用类中说明的非静态成员,但可以引用类中说明的静态成员。若静态成员函数中要引用非静态成员时,则可通过对象来引用。在类体外定义静态成员函数时,不使用static。在main()函数中,调用静态成员函数的形式为:
            <类名>::<静态成员函数名>(<参数表>)

考点14 常对象

  所谓常对象就是指使用关键字const修饰的对象。也可以叫做const对象。一般,能作用于const对象的函数只有构造函数与析构函数,因为const对象被看做只能生成与撤销、而不能被访问的对象。常对象在定义时必须进行初始化,并且不能被更新。常对象的定义形式为:
          <类名>const<对象名>
          或const<类名><对象名>

考点15 常成员函数和常数据成员

  1.常成员函数
  所谓常成员函数就是指使用关键字const声明的成员函数。常成员函数的声明形式为:
          <返回类型><成员函数名>(<参数表>)const;
  const也是类型的一部分,在const成员函数的定义与声明时都要写上。常对象和一般对象都可以调用常成员函数,而一般成员函数只能由一般对象调用。
  2.常数据成员
  所谓常数据成员就是指使用关键字const声明的数据成员。常数据成员的定义形式与一般常量的定义形式相同,只不过常数据成员的定义必须出现在类体中。常数据成员必须进行初始化,并且不能被更新。常数据成员只能通过构造函数的成员初始化列表进行初始化。

6.7 友元

考点16 友元函数和友元类

  1.友元函数
  友元可以是一个函数,也可以是一个类,前者称为友元函数,后者称为友元类。友元函数是一种定义在类外部的普通函数,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面要加关键friend。友元函数不是成员函数,但是它可以访问类中的听有成员友兀函数提高了程序的运行效率,但也破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员友元函数常常是另一个类的一个成员函数,这样通过友元函数可以使一个类对象直接访问另一个类对象的私有成员。友元函数作为一个类成员函数时,除了应在它所在的类定义中声明之外,还应在另一个类中声明它的友元关系,声明格式为:
  friend<函数返回类型><函数所在类名>::<函数名>(<参数表>
  2.友元类
  友元类是指将一个类声明为另一个类的友元也就是当一个类作为另一个类的友元时,这个类的所有成员函数都是另一个类的友元函数。

小提示:
  友元关系声明可以出现在类的私有部分,也可以出现在公有部分;友元关系是单句的,并且只在两个类之间有效。

6.8 对象数组与对象成员

考点17 对象数组

  所谓对象数组是指数组元素为对象的数组,对象数组中的每个元素都是同一类的对象。
  对象数组的定义为:
        <类名><数组名>[<大小>]…
  访问对象数组成员的一般形式为:
        <数组名>[<下标>].<成员名>

小提示:
  当对象数组生命周期结束之后,C++系统为对象数组的每个元素调用一次析构函数。

考点18 对象成员

  可以在一个类中说明具有类的类型的数据成员,这些成员称为对象成员。说明对象成员的一般形式为:
        class<类名>{
            <类名1>  <对象成员名1>
            <类名2>  <对象成员名2>
        …
            <类名n>  <对象成员名n>
       };
  当类中有对象成员时,该类的构造函数要调用这些对象成员所在类的构造函数,并采用成员初始化列表的方法为对象成员进行初始化。该类的构造函数的定义形式为:
<类名>::<类名>(<总形参表>):<对象成员名1>(<形参表1>),<对象成员名2>(<形参表2>),…<对象成员名n>(<形参表n>)
    {
      //类成员的初始化
}
  对对象成员的构造函数的调用顺序取决于这些对象成员在类中说明的顺序,与它们在成员初始化列表中给出的顺序无关。析构函数的调用顺序与构造函数正好相反。

6.9 类模板

考点19 类模板的定义和使用方式

  函数模板和类模板统称为模板。对象是类的特例,类也可以看做类模板的特例。与函数模板一样,使用类模板可以为类定义一种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值能取任意类型(包括系统定义的和用户定义的)但函数模板与类模板也有许多不同,主要是对由函数模板生成的模板函数的调用是由编译器自动决定的,而对类模板的解释由程序设计者自行指明。类模板使用时需要注意的几点:
  (1)定义一个类模板时,必须以关键字template开始,后面是尖括号括起来的类型形参列表,然后是类声明:
          template
              class类名{…};
  (2)每一个类模板的成员函数的外部定义必须以类型形参开始,此外还应加上函数类型返回值、类范围、函数名和形参列表:
          template
          <函数返回类型><类名>::<函数名>()
          {
   //函数体
     };
  (3)类模板是类的抽象类型,它的实例化是生成一个具体的类,形式如下:
  <类名><模板实参表><对象名>;
  或<类名><模板实参表><对象名>(<构造函数实参表>);

小提示:
  模板一经实例化,便可以且其创建对象。

(编辑:)