1 / 25

c.R c.setr( ) c.getr( ) c.longs( ) c.area( )

c.R c.setr( ) c.getr( ) c.longs( ) c.area( ). d.R d.setr( ) d.getr( ) d.longs( ) d.area( ). 随机数. 随机数. 函数代码. 函数代码. 函数代码. 函数代码. 函数代码. 函数代码. 函数代码. 函数代码. 圆类的对象 c. 圆类的对象 d. 对于: circle c, d ;编译系统为 2 个对象分配空间的情况如下:.

cherie
Download Presentation

c.R c.setr( ) c.getr( ) c.longs( ) c.area( )

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. c.R c.setr( ) c.getr( ) c.longs( ) c.area( ) d.R d.setr( ) d.getr( ) d.longs( ) d.area( ) 随机数 随机数 函数代码 函数代码 函数代码 函数代码 函数代码 函数代码 函数代码 函数代码 圆类的对象c 圆类的对象d 对于: circle c, d ;编译系统为2个对象分配空间的情况如下: 可以看出,两个对象在内存中各自占用不同的存储空间,可以说,两个对象都有类中所有成员的拷贝。

  2. 类实际上就是一种用户定义的数据类型,每当生成类的对象时,系统为每个对象分配空间存放类中的所有成员,每个对象中都有类中所有成员的拷贝,然而,在实际应用中,常常希望程序中所有同一类的对象共享某一成员,通常指数据成员,比如同一学校中所以学生对象中的学校名称成员,以保证数据的一致性及简化操作。解决办法就是将需要共享的成员说明成类中的静态成员。类实际上就是一种用户定义的数据类型,每当生成类的对象时,系统为每个对象分配空间存放类中的所有成员,每个对象中都有类中所有成员的拷贝,然而,在实际应用中,常常希望程序中所有同一类的对象共享某一成员,通常指数据成员,比如同一学校中所以学生对象中的学校名称成员,以保证数据的一致性及简化操作。解决办法就是将需要共享的成员说明成类中的静态成员。

  3. 3.5 静态成员 • 静态数据成员 静态数据成员在内存中仅有一个拷贝,为类的所有对象共享。 静态数据成员的使用方法: (1)静态数据成员的定义与一般数据成员的定义方法一样,但前面要加上关键字static (2)静态成员由于为所有的对象共享,所以必须要初始化,而且一般不在构造函数中初始化。初始化格式为: 类型 类名::静态数据成员名=初始值 (3)引用静态数据成员的格式为: 类名::静态数据成员名

  4. 静态数据成员是指在类中说明的、用关键字 static 修饰的数据成员。例: class X { private: int d; static int s;//定义静态数据成员 public: … … }; int X :: s=5; //初始化静态数据成员 该类中静态数据成员是私有类型,类外不能访问

  5. 定义静态数据成员,该数据成员为公有成员 初始化静态数据成员 引用静态数据成员 class sample { private: int n; float m; public: static int s; … … … }; int sample::s=0; void main() { … … … cout<<"s="<<sample::s<<endl; … … … } 该类中静态数据成员是公有类型,类外可以访问

  6. s n n sample( ) sample( ) 函数代码 函数代码 display( ) display( ) 函数代码 函数代码 b对象 a对象 0 2 5 2 5 class sample { private: int n; static int s; public: sample( int i ) { n=i; s=i; } void display( ) { cout<<“n=”<<n<<‘\t’; cout<<“s=”<<s<<endl; } }; int sample::s=0; 静态数据成员由于为所有的对象共享,所以我们也把静态数据成员称为类变量。非静态数据成员属于一个具体的对象,我们称为对象变量(实例变量) void main() { sample a(2), b(5); a.display( ); b.display( ); } 输出: n=2 s=5 n=5 s=5

  7. 定义静态数据成员,由于n是私有成员,不能在类外访问定义静态数据成员,由于n是私有成员,不能在类外访问 初始化静态数据成员 定义了一个对象数组s,数组元素是四个对象。 #include <iostream.h> class sample { private: static int n; public: sample() { n=n+1;} void display() { cout<<"n="<<n<<endl; } }; int sample::n=0; void main() { sample *p=new sample,s[4]; s[0].display(); s[1].display(); s[2].display(); s[3].display(); p->display(); } 由于 n 为所有的对象共享,不属于没个对象,所以每创建一次对象n值加1。 输出为: n=5 n=5 n=5 n=5 n=5

  8. 静态成员函数 静态函数成员在内存中仅有一个拷贝,为类的所有对象共享。 静态函数的使用方法: (1)和静态数据成员相同,静态成员函数是用关键字static 修饰的成员函数。 (2)静态函数成员只能访问静态数据成员,不能访问该类中的非静态数据成员。 (3)引用静态函数成员的方式和引用静态数据成员的方式一样,格式为: 类名::静态函数成员名(<参数列表>)

  9. 静态函数成员的定义,只能访问静态数据成员n,不能访问数据成员m静态函数成员的定义,只能访问静态数据成员n,不能访问数据成员m 静态函数成员的调用 class sample { private: static int n; float m; public: void sub( ) { …… } static void add( ) { …… } ……… }; void main( ) { … … sample::add( ); … … }

  10. 静态函数成员访问静态数据成员 静态函数的调用 #include <iostream.h> int s; class sample { private: static int n; public: sample(int i) { n=i; } static void add( ) { s=s+n; } }; int sample::n=0; void main() { sample a(2),b(5); sample::add( ); cout<<"s="<<s<<endl; } 输出:s=5 为了节省内存,所有对象的函数成员在内存中共享一个副本,所以静态函数成员只有逻辑上的意义,称为类方法。非静态函数成员逻辑上属于一个具体的对象,我们称为对象方法(实例方法)

  11. #include <iostream.h> class sample { public: static int n; static void add( ) { n=n+1; cout<<"n="<<n<<endl; } }; int sample::n=0; void main( ) { sample::n=5; sample::add( ); } 输出: n=6 该程序说明静态数据成员和静态函数成员不依赖于对象的存在,但是非静态成员只有在对象存在的时候才有意义。所以我们把静态数据成员称为类变量,把静态函数成员称为类方法。 该程序没有创建对象

  12. q对象首址 p对象首址 x x 3 5 demo( int ) demo( int ) 函数代码 函数代码 函数代码 函数代码 demo( ) demo( ) add( ) add( ) 函数代码 函数代码 dis( ) dis( ) 函数代码 函数代码 q对象 p对象 到底调用的哪一个对象的add()成员,编译器怎么知道的? 3.6 this指针 #include <iostream.h> class demo { private: int x; public: demo(int m) { x=m; } demo( ) { } void add(int n) { x=x+n; } void dis( ) { cout<<x<<endl; } }; void main() { demo p(5),q(3); p.add(4); p.dis( ); q.add(2); q.dis( ); }

  13. 每个函数都有一个指向该类对象的一个指针变量作为第一个形参,该指针变量是系统隐含的,我们称为this指针。每个函数都有一个指向该类对象的一个指针变量作为第一个形参,该指针变量是系统隐含的,我们称为this指针。 this-> this-> 在成员函数体里,我们可以访问this这个指针变量。 &p, &q, #include <iostream.h> class demo { private: int x; public: demo(int m) { x=m; } demo() {} void add( int n) { x= x + n; } void display() { cout<<x<<endl; } }; void main() { demo p(5),q(3); p.add( 4); p.display(); q.add( 2); q.display(); } demo *this, 每个对象在调用函数成员时,都把自己的地址作为第一个参数传递给函数成员,不过该参数是系统隐含的。

  14. 系统隐含的,不需要用户定义。 #include <iostream.h> class demo { private: int x; public: demo( demo *this, int m) { this->x = m; } demo() {} void add( demo *this, int n) { this->x = this-> x+n; } void display( demo *this) { cout<<this->x<<endl; } }; void main() { demo p( &p , 5),q( &q , 3); p.add( &p , 4); p.display( &p ); q.add( &q , 2); q.display( &q ); } 注意: 类的每一个成员函数都有一个隐 含定义的,指向该类对象的一个指针 变量,我们称为this指针。 每当一个对象调用成员函数时,this指针被初始化为调用该成员函数的对象的地址。

  15. this指针在每一个成员函数中系统都隐含定义并初始化了,所以我们可以在每一个成员函数中都可以使用this指针this指针在每一个成员函数中系统都隐含定义并初始化了,所以我们可以在每一个成员函数中都可以使用this指针 #include <iostream.h> class demo { private: int x; public: demo(int m) { this->x = m; } demo( ) { } void add(int n) { this->x = this-> x+n; } void display( ) { cout<<this->x<<endl; } }; void main() { demo p(5),q(3); p.add(4); p.display( ); q.add(2); q.display( ); } 输出: 9 5 注意:静态函数成员由于为类中所有的对象共享,逻辑上为类所有,所以没有this指针。

  16. 对象s3调用add( )函数成员,所以this指针指向对象s3。 该语句相当于:s3.n=s1.n+s2.n 返回了对象本身即s3 #include <iostream.h> class sample { private: int n; public: sample() { } sample(int m) { n=m; } sample add( sample s1,sample s2 ) { this->n = s1.n+s2.n; return(*this); } void display() { cout<<"n="<<n<<endl; } }; void main() { sample s1(10),s2(5),s3; cout<<"s1::"; s1.display(); cout<<"s2::"; s2.display(); s3.add(s1,s2); cout<<"s3::"; s3.display(); } 输出: S1::n=10 S2::n=5 S3::n=15

  17. 静态数据成员,存放国籍 初始化有参对象的构造函数。 例:Person p1(“Li”,25,’f’) 初始化无参对象的构造函数。 例:Person p2; 用对象初始化对象的构造函数 例:Person p3( p1 ); 析构函数,撤销对象 对无参对象赋值的成员函数 例:p2.Register( “Hu”,23,’f’); 静态函数成员,修改国籍 静态函数成员,输出国籍 class Person { private: char Name[20]; int Age; char Sex; static char Country[20]; public: Person ( char *, int, char ); Person ( ); Person ( Person &obj ); ~Person( ); void Register( char *, int, char ); void GetName( char * ); int GetAge( ); char GetSex( ); static void ChangeCountry( char * ); static void GetCountry( char * ); } ; char Person::Country[20]=“China” ; person类的定义

  18. 3.6 对象的引用 引用就是别名。当建立引用时,必须用一个已经定义的变量或者对象的名字来定义它。在引用被定义后,引用就作为原变量或者原对象的别名来使用,对引用的改动就是对原目标的改动。 定义格式: 类名 &引用对象名= 已定义对象名; 例如: peason p1(“zhang” , 25 , ’f’); peason &p2 = p1; 为对象p1定义了一个引用类型p2,换句话说,为对象p1 起了一个别名p2,即p2和p1都是对同一个对象的引用。

  19. 对象a b.R b.circle(int) b.ciecle( ) b.serr( ) b.getr( ) a.R a.circle(int) a.circle( ) a.setr( ) a.getr( ) 函数代码 函数代码 函数代码 函数代码 … … … 对象b 5 10 void main() { circle a(5); circle &b = a; b.setr(10); cout<<a.getr( )<<endl; cout<<b.getr( )<<endl; } 输出: 10 10

  20. 函数原型 a对象 b对象 值传递 R 5 5 R circle(int) 函数代码 circle( ) 函数代码 getr( ) 函数代码 … … … void main() { void f (circle); circle a(5); cout<<a.getr( )<<endl; f(a); } void f (circle b) { cout<<b.getr( )<<endl; } 输出: 5 5 注意:当对象的数据成员比较多时,使用对象直接作为函数参数会在赋值的操作上浪费大量系统资源,造成效率不高。

  21. a对象 R circle(int) 函数代码 circle( ) 函数代码 setr( ) 函数代码 getr( ) 函数代码 … … … void main() { void f (circle &); circle a(5); cout<<a.getr( )<<endl; f(a); } void f (circle &b) { cout<<b.getr( )<<endl; } b对象 15 5 b.setr(15); 输出: 5 5 输出: 5 15 注意:使用对象的引用类型作为函数参数,优点是没有值传递的过程,也不需要另外分配内存空间,只是一个起别名的过程,效率高。缺点是通过引用名可能对原目标改动。

  22. a对象 R circle(int) 函数代码 circle( ) 函数代码 setr( ) 函数代码 getr( ) 函数代码 … … … void main() { void f ( circle &); circle a(5); cout<<a.getr( )<<endl; f(a); } void f ( circle &b) { b.setr(15); cout<<b.getr( )<<endl; } b对象 5 const const //编译错误 //编译错误 注意:利用关键词const修饰的对象是常对象,常对象只能引用原对象的值,不能去更新原对象的值。

  23. p1是常对象,其值不能更改 p2是常对象,只能引用p1的值,不能更改p1的值,我们也称p2为常引用 b是常对象,只能引用a的值,不能更改a的值,我们也称b为常引用 常对象和常成员函数 • 常对象:利用关键词const修饰的对象是常对象,常对象只能引用原对象的值,不能更新原对象的值。 const peason p1(“zhang” , 25 , ’f’); peason p1(“zhang” , 25 , ’f’); const peason &p2 = p1; void f (const circle &b) { … … …} void main() { circle a(5); ……… f(a); }

  24. a对象 R circle(int) 函数代码 circle( ) 函数代码 setr( ) 函数代码 getr( ) 函数代码 … … … 由于b是常对象,常对象不能调用普通函数成员 • 常成员函数:利用关键词const修饰的函数成员我们称为常成员函数。常对象只能访问常成员函数,不能访问一般函数成员。 b对象 void main() { void f (const circle &); circle a(5); cout<<a.getr( )<<endl; f(a); } void f (const circle &b) { cout<<b.getr( )<<endl; } 5

  25. 常对象b调用常成员函数getr( ) const 常对象b也可以调用常成员函数longs( )和area( )。 const #include <iostream.h> class circle { private: double R; public: circle(double r) { R=r; } circle( ) { } void setr(double r ) { R=r; } double getr( ) { return(R); } double longs( ) { return( 2*3.14*R); } double area( ) { return(3.14*R*R); } }; void main() { void f(const circle &); circle a(5); cout<<a.getr( )<<endl; f(a); } void f(const circle &b) { cout<<b.getr( )<<endl; } const

More Related