█████继TD发布C语言第三章[数据抽象]█████

社区服务
高级搜索
猴岛论坛辅助工具█████继TD发布C语言第三章[数据抽象]█████
发帖 回复
正序阅读 最近浏览的帖子最近浏览的版块
9个回复

█████继TD发布C语言第三章[数据抽象]█████

楼层直达
丶爱很简单

ZxID:1664691

等级: 中将
```

举报 只看楼主 使用道具 楼主   发表于: 2009-02-02 0
— 本帖被 幻想. 执行提前操作(2009-02-09) —
█████C语言教学-第三章█████

第三章  数据抽象



目标
1.定义类
   解释成员变量
   解释成员函数
   解释类的作用域
   解释静态成员
2.定义对象
   声明对象
   解释new 和 delete
   解释初始化
   解释对象操作


1.类
类是C++语言中实现面向对象编程(OOP)功能的一种手段。声明了某种结构后,就可以定义该类型的变量,同样,声明了某个类后,就可以定义该类的对象。对像是类的特定实例。定义了某个类后,可以声明该类的多个对象。

1.1成员变量

在类中,对象的特征是由变量表示的,称为类的属性,也称为成员变量。
类的成员可以在类的公有部分或者么有部分中进行声明。

公有部分构成构成类的对象的接口。
在公有部分声明的数据成员和函数可以被该类外部的任何函数访问。
对于类的外部来说,私有数据无法访问。而且,其他类的私有数据对于当前类来说也是隐藏的。

在私有和公有部分都可以声明变量和函数,但在实践中,大多数情况下只在类的私有部分声明变量,而函数则在公有部分声明。默认情况下,类的所在成员都是私有的。

类的私有部分和公有部分分别由关键字private和public指定。

在类中声明(无论是在公有部分还是在私有部分)的所有函数都是类的成员。
关键字private和public决定了类成员的可访问性。
程序中的任何函数都可以访问类公有部分的变量和函数,但是只能通过类的公有成员函数访问该类中的私有成员。 这种对数据成员的隔离称为信息息隐藏。


const成员变量

一般用在定义接口

const限定符通知编译器该变量的值在整个程序中是恒定的。

任何试图修改由const限定的变量的尝试都将导致编译器报告错误。

const限定符确保不会意外地改变变量的内容。

1.2成员函数
在类中声明成员函数时,必须定义其返回值以及参数列表。在成员函数定义时函数头需要使用作用域操作符(::)指定该函数所属的类。

同一类的所有对象共享相同的成员函数。即共用一份成员函数。
成员变量用的是副本。

构造函数
专门用来初始化对象的函数。
构造函数是一种自动初始化对象的特殊成员函数。
每当创建了对象,就会执行构造函数。

构造函数与所有其他成员函数的区别在于它与自己所属的类同名。
可以在类中声明并定义构造函数,也可以在类中声明而在类外定义。

C++中构造函数的一般语法是:

class username
{
    ......
public:
    username();    //构造函数
};

username::username() //在类代码外部定义的构造函数
{
    ......
}


构造函数没有任何类型的返回值,它由系统自动调用,在创建类的局部对象或临时对象时也会调用构造函数。
当类具有构造函数时,该类的所有对象都会被初始化。
有时,需要提供多种初始化类的对象的方式,这可以通过提供多个构造函数来实现。
默认构造函数是不带任何参数的构造函数。
即使在程序中没有显式地写出构造函数,编译器也会自动生成它。

只要各个构造函数的参数有差别,编译器就可以在不同情况下选择使用正确的构造函数。

析构函数
当对象不再存在(即超出它的作用域)时,将调用一个称为函数的特殊成员函数。
析构函数是对象销毁时自动调用的成员函数。
析构函数不能从类中直接调用。当对象过期时,编译器会自动生成对析构函数的调用。

析构函数也和类同名,但是在其函数名之前有一个波浪号(~)。
C++中析构函数的一般语法为:

class username
{
    ......
public:
    ~username();      //析构函数
};

析构函数没有返回类型,而且不带参数。

析构函数最常见的用途是释放构造函数中使用new操作符为对象分配的内存。
eg:
#include<iostream.h>
#include<string.h>
class string
{
private:
          char *str;
public:
          string()      //构造函数1
        {
                cout<<"调用了默认构造函数。";
        }
          string(char *s)   //构造函数2
        {
                int length=strlen(s);
                str=new char[length+1];
                strcpy(str,s);
                cout<<"第二个构造函数。";
          }

        ~string()      //析构函数
          {
                  cout<<"调用默认析构函数。";
          }
};

int main()
{
          string obj;        //调用了默认构造函数
          string obj1("hello");    //调用带单个参数的构造函数
          return 0;
}
在构造函数中使用new操作符为一个字符串分配了内存。计算了字符串的长度,并相应地分配了空间。


1.3作用域

变量的作用域决定变量在何处有效、在何处创建以及在何处销毁(即超出作用域)。

作用域是由离变量“最近的”一对括号定义的。

作用域解析操作符用于访问成员函数和全局变量。
成员函数的参数类型必须与在类中所声明的类型完全匹配

在全局变量与局部变量同名的情况下,作用域解析操作符还可以用来引用全局变量名。
使用的语法是:
::global_variable
通过区分同名变量,作用域解析操作符使得命名变量时可以具有更大的自由度,但不应滥用这个功能。如果两个变量的用途不同,它们的名称应该反映出这种区别。

1.4静态成员

当同一类的所有对象必须共享某些共同的信息时,静态数据项非常有用。
如果类中的某个数据项被定义为static,则无论创建了多少个对象,都只会为整个类创建一个这样的数据项。
定义的静态成员变量具有一些与普通的静态变量相似的特征,它只在类中可见,但是其生命周期贯穿整个程序。
静态数据成员的一般语法是:
static data_type variable


静态数据成员应当在main()程序开始之前创建并初始化。

静态成员的访问规则与其他数据成员相同。
如果将静态成员声明为类的私有成员,非成员函数将无法访问它。如果将它声明为公有的,则该类的任何成员都能够访问它。
声明一个静态数据成员后,类的所有实例共享的只是该静态数据成员的单个一个副本,这意味着这个静态成员成为了该类的全局数据。使用静态数据成员能够显著减少对全局变量的需求。

静态成员变量和函数

将成员声明为静态会限制其作用域,并使其独立于该类的各个对象,此功能对成员函数和数据成员同样有用。
静态成员函数只能操纵类的静态数据成员。

静态成员函数不是类的对象的一部分,它没有this指针。要调用静态成员函数,不需要使用object.function()语法。可以使用类名和作用域解析操作符直接调用它。
eg:

#include<iostream.h>
class alpha
{
private:
  static int count;//静态数据成员
public:
  alpha()
  {
        count++;
    }
    static void display_count()  //静态成员函数
  {
        cout<<count;
        cout<<endl;
  }
};
int alpha::count=0;
int main()
{
      alpha::display_count();      //创建任何对象之前     count值是0
      alpha obj1,obj2,obj3;
      alpha::display_count();   //创建三个对象之后    count值3
      return 0;
}



1.5this指针

this指针用于显式地引用对象的成员。
一个类可以有许多个对象。
在成员函数中访问对象的成员时不需要使用该对象的名称。
关键字this给出了调用成员函数的对象的地址。只要调用成员函数,编译器就会把调用该函数的对象的地址赋给this指针。

this指针可以和箭头操作符一起使用,以访问它所指向的对象的成员。
this->age=5;  //访问数据成员age
this->getdata();          //访问成员函数
和JAVA显式方法不一样,呵呵
 

eg:

#include<iostream.h>
class person
{
private:
    int age;
public:
  void display();
};
void person::display()
{
      this ->age=25;          //与age=25一样
  count<<this->age;    //与cout<<age一样
        count<<endl;                         
};
int main()
{
      person jack;
      jack.display();
      return 0;
}


2.对象
对象是基本的运行时实体

2.1声明对象的语法
class_name object_name;

一旦声明后,就可以使用圆点操作符和该对象的名称来访问它的公有成员。

2.2new 和 delete

new 用于创建对象,delete用来销毁它们
在C++中,可以用malloc()和free()函数
但new 和 delete是C++语言内置的,而不是附加函数。

new操作符用于为类的对象创建内存空间,并返回指向所创建的对象的指针。

new操作一般语法是:
data_type pointer_variable=new data_type;


data_type可以是short,int,float,char等基本数据类型,或者是类的对象。

int *p;                //指向int类型的指针
float *f;              //指向float类型的指针
p=new int;          //为int类型分配内存
f=new float        //为float类型分配内存


如果成功调用了new,将返回指向所分配的内存空间的指针。否则,如果内存空间不足或者检查到错误,则返回0。

和同样的方法为对象分配内存,假定有一个类student
student *stu_ptr;  //指向student类型的对象的指针
stu_ptr=new student;  //指向新的student对象



new操作符类似于C语言中使用的malloc()函数。new操作符的优越之处在于,它返回一个指向适当数据类型的指针,而malloc()的指针必须强制转换为适当类型。


由new创建的对象会一直存在,直到由delete显式销毁时为止。这样它所占用的内存空间就可以重新使用。
delete操作符的一般语法为:
delete pointer_variable;

eg:

int *ptr;      //*ptr指向地址
ptr=new int;//分配空间
*ptr=12;   //*ptr指地址里的具体内容值
cout<<*ptr;
delete ptr;  //delete只须定义指针名,而不需要带有数据类型



假设在函数中使用了new,而且该函数使用一个局部指针变量指向此内存。当该函数终止时,该局部变量(即该指针)将被销毁,但是此内存仍然占用着,程序的其他部分无法访问它所占用的空间。因此,在使用完内存时用delete将其释放,请注意,不要使用指向已删除了的内存的指针。


类似技术分配由可变长数组组成的内存块。用delete[]删除数组的方法。

int *ptr;
ptr=new int[100]
delete[] ptr;

指向对象的指针与指向对象数组的指针之间的语法上是没有区别的。若不使用不带括号的delete,就不能删除全部数组。

配对使用此两种函数:

new & delete;
malloc() & free()
用delete删除使用malloc()函数分配的内存的变量是错误的
用free()函数释放使用new分配给变量的内存空间也是error的。



2.3.初始化
调用构造函数不是程序员所能选择的,它在定义对象时由编译器执行。

2.4对象操作

对象数组

类是一种模板,它可以包含数据项以及操作数据项的成员函数。可以声明特定的类的多个对象,也可以像声明所有其他数据类型的数组一样来声明和使用对象数组。

EG:对象数组的用法


#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<iostream.h>
class student
{
private:
      int RollNum;
      char Name[26];
      float Marks[7];
      float Percent;
public:
      float GetDetails();
      float PrintDetails();
};
float student::GetDetails()
{
      int ctr=1;
      float total=0;
      cout<<"序号:";
      cin>>RollNum;
      cout<<"姓名:";
      cin>>Name;
      cout<<"成绩:";
      while(ctr<7)
      {
              cout<<"请输入科目"<<ctr<<"获得的成绩:";
              cin>>Marks[ctr];
              total=total+Marks[ctr];
              ctr=ctr+1;
      }
      percent=total/6;
      return 0;
}

float student::PrintDetails()
{
        cout<<"序号:"<<RollNum;
        cout<<endl;
        cout<<"姓名:"<<Name;
        cout<<endl;
        cout<<"平均分:"<<percent;
        cout<<endl;
        return 0;
}

int main()
{
      student records[3];
      int x=0;
      int y=0;
      while(x<3)
      {
            records[x].GetDetails();
            x=x+1;
      }
      while(y<3)
      {
            records[y].Printdetails();
            y=y+1;
        }
        return 0;
}

声明一个对象数组,类的成员使用由下标限定的数组名进行访问。即records[y].printdetails();
对于不同的下标值,这条语句将调用不同对象的成员函数。

初始化对象数组
对象数组也可以在声明时初始化。例:

#include<iostream.h>
#include<string.h>
class Employee
{
private:
      char name[40];
      int age;
      double salary;
public:
      Employee(char *n,int a,double s);//构造函数
      void display();
};
Employee::Employee(char*n,int a,double a)
{
      strcpy(Name,n);
      age=a;
      salary=s;
};
void employee::display()
{
      cout<<name;
      cout<<endl;
      cout<<age;
      cout<<endl;
      cout<<salary;
      cout<<endl;
}
int main()
{
      Emlpoyee ManyEmps[3]=
      {
                Employee("Slaycke Xulmberg",33,96000),
                Employee("Peorje Posteau",45,350000),
                Employee("Teoberque jailbird",50,110000)
        };

        int x=0;
        while(x<3)
        {
                ManyEmps[x].display();
                x=x+1;
        }
        return 0;
}


对象指针

指针既可以指向简单数据类型的变量,也可以指向对象。
声明指向特定类的对象的指针的方法与声明指向任何数据类型的变量的指针相同。

date *today_ptr;      //指向date类型 的对象的指针
today_ptr=new date; //指向新的date对象

当我们需要引用today_ptr所指向的对象中的任何成员函数时,不使用圆点操作符(.)。

圆点操作符要求其左侧的标识符是对象

today_ptr是指向对象的指针,因此需要使用简头操作符(->)来实现。
today_ptr->getdata();


补充:静态成员函数对于它所属的类中的成员是“全局”的



我应该没发错吧.o(∩_∩)o...
本帖de评分: 1 条评分 DB +50
DB+50

精品文章

iverson333

ZxID:2371692

等级: 上等兵
很多事情就像看A片,看的人觉得很爽,做的人未必。
举报 只看该作者 9楼  发表于: 2009-02-10 0
看不懂
问题依旧,答案永恒
pop宝贝

ZxID:4145198

等级: 新兵
举报 只看该作者 8楼  发表于: 2009-02-09 0
C语言学习了之后会对以后的要学的程序语言会有很大的帮助的!!
而且这些是最基础的语言!!!

C语言还算好,比较简单!!!呵呵!
伤々傀儡

ZxID:1510445

等级: 贵宾
丨爺".硪卜是RMB! 做不到人人都喜欢!

举报 只看该作者 7楼  发表于: 2009-02-07 0
请 重发一次发到 QQ仙境 板块。。。 我帮你点亮。 移过来。。。 

发好联系我。

楼主留言:

点亮也没用,就这样挺好的。反正我都是复制的。

ˊ謎亂﹏

ZxID:1171742

等级: 元老
sHadow丶Davis

举报 只看该作者 6楼  发表于: 2009-02-07 0
这样发不懂看啊..

楼主留言:

如果叫我就这样看能看懂我就是天才了^_^


寂寞帝。
thedling

ZxID:1693239

等级: 贵宾
举报 只看该作者 5楼  发表于: 2009-02-07 0
不过似乎你教的太快了,都指针了啊~~~

世界上有两样东西是最震撼人心的,一样是天上的星空,还有一样是我们心里高尚的道德标准。
thedling

ZxID:1693239

等级: 贵宾
举报 只看该作者 4楼  发表于: 2009-02-07 0
好,非常好,支持!!!

楼主留言:

谢谢o(∩_∩)o...


世界上有两样东西是最震撼人心的,一样是天上的星空,还有一样是我们心里高尚的道德标准。
就死啦

ZxID:2052575

等级: 中士
我最崇拜的就是那些做G的人!!  

举报 只看该作者 地板   发表于: 2009-02-03 0
是真的吗?不要骗我们啊!          
LegendHeaven

ZxID:3233066

等级: 上校
记于我心,君可自便。

举报 只看该作者 板凳   发表于: 2009-02-03 0
  迷惑啊不过很想学

无限期潜水中。。。
167425174

ZxID:1796084

等级: 上尉
老板,你这脸皮多少钱一斤?
举报 只看该作者 沙发   发表于: 2009-02-03 0
等我想学了我就会学习的
这脸皮是真皮的么?
« 返回列表
发帖 回复