[C++]类和对象(二)

来源:互联网 发布:程序员必备刷题网站 编辑:程序博客网 时间:2024/05/17 08:06

类和对象

类的对象如何引用私有数据成员

1、通过公有函数为私有成员赋值

class  Test{

int  x ,  y;

    public:

       void Setxy(int  a, int b){x=a;y=b;}

       void  Printxy(void) {cout<<"x="<<x<<'\t'<<"y="<<y<<endl;}

} ;

void  main(void)

{    Test    p1,p2;

    p1.Setxy(3, 5);调用公有函数为私有对象赋值

   p1.Printxy( );

}

2、利用指针访问私有数据成员

class  Test{

int  x,y;

   public:

       void Setxy(int  a, int b) {x=a;y=b;}

       void  Getxy(int  *px,  int *py) {*px=x;*py=y;} //提取x,y值

       void  Printxy(void){cout<<"x="<<x<<'\t'<<"y="<<y<<endl;  }

};

void  main(void)

{    Test    p1,p2;

      p1.Setxy(3,5);

      int  a,b;

      p1.Getxy(&a,  &b);//将   a=x,   b=y

      cout<<a<<'\t'<<b<<endl;  

}

输出: 3   5

3、利用函数访问私有数据成员

class  Test{

int  x,y;

   public:

       void Setxy(int  a, int b) {x=a;y=b;}

       int  Getx(void) { return   x;} //返回x值

       int  Gety(void) { return   y;} //返回y值

       void  Printxy(void){cout<<"x="<<x<<'\t'<<"y="<<y<<endl;  }

};

void  main(void)

{    Test    p1,p2;

      p1.Setxy(3,5);

      int  a,b;

      a=p1.Getx( );     b=p1.Gety();  //将   a=x,   b=y

      cout<<a<<'\t'<<b<<endl;  

}

函数值就是私有成员变量的值

 

4、利用引用访问私有数据成员

class  Test{

int  x,y;

   public:

       void Setxy(int  a, int b){x=a;   y=b;}

      void  Getxy(int &px,  int &py) { px=x;py=y;} //提取x,y值

      void  Printxy(void){cout<<"x="<<x<<'\t'<<"y="<<y<<endl;  }

};

void  main(void)

{     Test    p1,p2;

       p1.Setxy(3,5);

       int  a,b;

       p1.Getxy(a,  b);//将   a=x,   b=y

       cout<<a<<'\t'<<b<<endl;  

}

输出: 3   5

 

成员函数的重载

类中的成员函数与前面介绍的普通函数一样,成员函数可以带有缺省的参数,也可以重载成员函数 。

重载时,函数的形参必须在类型或数目上不同。

可以有缺省参数的成员函数,若形参不完全缺省,则必须从形参的右边开始缺省。

缺省参数的成员函数

class A{

float  x,y;

public:

float Sum(void) {   return  x+y;   }

void Set(float a,float b=10.0) {    x=a;y=b;}

      void Print(void) {cout<<"x="<<x<<'\t'<<"y="<<y<<endl; }

};

void main(void)

{A a1,a2;

a1.Set (2.0,4.0);   不缺省参数,a1.x=2,  a1.y=4

cout<<"a1:  ";  a1.Print ();

cout<<"a1.sum="<<a1.Sum ()<<endl;

a2.Set(20.0);     缺省参数,a2.x=20,  a2.y=10

cout<<"a2:  ";  a2.Print ();

cout<<"a2.sum="<<a2.Sum ()<<endl;

}

定义类的指针及如何用指针来引用对象

class A{

float  x,y;

public:

float Sum(void) {   return  x+y;   }

void Set(float  a,float  b) {    x=a;y=b;}

      void Print(void) {cout<<"x="<<x<<'\t'<<"y="<<y<<endl;   }

};

void main(void)

{A a1,a2;

A *p;//定义类的指针

p=&a1;//给指针赋值

            p->Set(2.0,  3.0);    //通过指针引用对象的成员函数

            p->Print();

            cout<<p->Sum()<<endl;

a2.Set(10.0, 20.0);   a2.Print();

}

定义类的数组及数组中元素的引用

void main(void)

{

Stu stu[3];//定义类的数组

Stu  *pstu;//定义类的指针

pstu=stu;//为指针赋值

int i;

stu[0].SetStudent (“A”,90,90);//通过数组元素的引用赋值

stu[1].SetStudent ("B",80,80);

stu[2].SetStudent ("C",70,70);

for(i=0;i<3;i++)

{

pstu->Show ();//指针变量指向数组元素

pstu++;//指针变量加一,指向下一元素

}

}

返回引用类型的成员函数(可以返回私有数据成员的引用)

class A{

float  x,y;

public:

float &Getx(void ) {   return  x;   }//返回x的引用

void Set(float a,float b) {    x=a;   y=b;   }

void Print(void) {   cout<<x<<'\t'<<y<<endl;   }

};

void main(void)

{A  a1,a2;

a1.Set (3,5);

cout<<"a1:  ";   a1.Print ();

a1.Getx()=30;//将a1对象中的x成员赋值

cout<<"changed  a1: ";

a1.Print ();

}

 

 

线性表的应用

线性表用来存放若干个整数,用一个指针指向其存放整数的首地址。当存放的数据大于原先开辟的空间时,线性表自动动态开辟空间,储存所有的整数。

线性表有三个参数来描述:指向线性表存储空间首地址的指针变量List;无符号整数nMax,指示表的最大长度;无符号整数nElem,指示表中实际所放的数据个数。

实际上,线性表相当于一个整型数组,List为数组的首地址,nMax为数组在内存开辟的空间数,nElem为数组中实际存放的元素个数。只不过数组的空间是动态开辟的。

class ListClass {

   int *List;    //指向线性表的指针

   unsigned nMax;    //表的最大长度

   unsigned nElem;    //表中当前的元素个数

  .......

};

 

1class ListClass {

   int *List;    //指向线性表的指针

   unsigned nMax;    //表的最大长度

   unsigned nElem;    //表中当前的元素个数

public:

void Init(int n=10);   //初始化针表,最大长度的缺省值为10

void Elem(int);//在线性表尾增加一个元素

int & Elem(unsigned n);//返回线性表中第n个元素的引用

unsigned Elem(void);//返回当前线性表中元素的个数

unsigned Max(void);//返回线性表的长度(占用空间数)

void Print(void);//输出线性表中所有的元素

int GetElem(int i);//返回线性表中第i个元素的值

void Destroy(void);//收回线性表占用的存储空间

};

2void ListClass::Elem (int elem) //在线性表尾增加一个元素

{nElem=nElem+1;

if(nElem>nMax)//空间不够,动态开辟存储空间

{int *list;

list=new int[nMax+1]; //开辟一较大的空间    重新定义一个指针list,用其开辟一较大的空间,将原有空间的数全部拷贝到新的空间,并将新的数据放在新空间内,同时将旧的空间收回,将线性表的指针指向新空间。

for(int i=0;i<nMax;i++)

list[i]=List[i];

nMax=nMax+1;

list[i]=elem;

delete []List;

List=list;

}

else{List[nElem-1]=elem;}

}

this 指针

不同对象占据内存中的不同区域,它们所保存的数据各不相同,但对成员数据进行操作的成员函数的程序代码均是一样的。

 

当对一个对象调用成员函数时,编译程序先将对象的地址赋给this指针,然后调用成员函数,每次成员函数存取数据成员时,也隐含使用this指针。

this指针具有如下形式的缺省说明:

   Stu   *const    this;  

即 this 指针里的地址是一个常量

·构造函数和析构函数是在类体中说明的两种特殊的成员函数。

·构造函数是在创建对象时,使用给定的值来将对象初始化

·析构函数的功能正好相反,是在系统释放对象前,对对象做一些善后工作。

·构造函数可以带参数、可以重载,同时没有返回值。

·构造函数是类的成员函数,系统约定构造函数名必须与类名相同。构造函数提供了初始化对象的一种简单的方法。

class A{

float  x,y;

public:

A(float a,float b){  x=a;   y=b;}//构造函数,初始化对象

float Sum(void) {   return  x+y;   }

void Set(float  a,float  b) {    x=a;y=b;}

Print(void) {  cout<<"x="<<x<<'\t'<<"y="<<y<<endl;}

};

void main(void)

{A a1(2.0, 3.0);//定义时调用构造函数初始化

A  a2(1.0,2.0);

a2.Set(10.0, 20.0);   //利用成员函数重新为对象赋值

           a1.Print();

a2.Print();

}

对构造函数,说明以下几点:

1.构造函数的函数名必须与类名相同。构造函数的主要作用是完成初始化对象的数据成员以及其它的初始化工作。

2. 在定义构造函数时,不能指定函数返回值的类型,也不能指定为void类型。

3. 一个类可以定义若干个构造函数。当定义多个构造函数时,必须满足函数重载的原则。

4.构造函数可以指定参数的缺省值。

5.若定义的类要说明该类的对象时,构造函数必须是公有的成员函数。如果定义的类仅用于派生其它类时,则可将构造函数定义为保护的成员函数。

 

由于构造函数属于类的成员函数,它对私有数据成员、保护的数据成员和公有的数据成员均能进行初始化。

 

·对局部对象,静态对象,全局对象的初始化对于局部对象,每次定义对象时,都要调用构造函数。

·对于静态对象,是在首次定义对象时,调用构造函数的,且由于对象一直存在,只调用一次构造函数。

·对于全局对象,是在main函数执行之前调用构造函数的

 

0 0