《静态类成员331静态数据成员希望数据为类的所有对象课件.ppt》由会员分享,可在线阅读,更多相关《静态类成员331静态数据成员希望数据为类的所有对象课件.ppt(35页珍藏版)》请在三一办公上搜索。
1、3.3 静态类成员3.3.1 静态数据成员 希望数据为类的所有对象共享,而不是每个类对象维持一个独立的数据成员。例如:计数在程序的任意一点一共创建了多少个此类类型的对象。静态数据成员对每个类类型只有一个拷贝,由该类对象共享访问。非静态数据成员对每个类对象都有自己的拷贝。可以实现信息隐藏,可以是private成员。3.3.1.1 类定义内声明在类体中数据成员声明前加上static关键字,使该数据成员成为静态的例如:class student int num;float score;public:static float passmark;static int passnum;,student(i
2、nt a,float f)num=a;score=f;3.3.1.2 类定义外初始化 语法:数据类型 类名:数据成员名=初值;注意:如果没有初值,系统自动初始化为0。整型const静态数据成员可以在类定义体内用常量值初始化,但仍要在类定义体外定义该数据成员且不能再指定初始值。静态数据成员的初始化不应该放在头文件中。一般放在类定义之后,main函数之前。产生类对象之前可能用到静态数据成员。例如:class Accout static const int namesize=16;static const char namenamesize;const int Accout:namesize;con
3、st char Accout:namenamesize=”saving account”;3.3.1.3 静态数据成员的访问,类的成员函数中访问:用静态数据成员名直接访问 非成员函数中访问public静态数据成员:类名:静态数据成员名 对象.静态数据成员名 指向对象的指针-静态数据成员名 例如:计数已创建对象的数目 class Data int num;float score;public:static int object;Data(int a,float f):num(a),score(f)object+;Data()object-;,3.3.2 静态成员函数 希望在产生对象之前访问pri
4、vate静态数据成员 3.3.2.1 声明与定义 在类内普通成员函数声明前加上static关键字,在类外定义前不需再加static。注意:静态成员函数没有this指针,不能访问类的非静态成员,只能访问类的静态数据成员或是调用其它静态成员函数。3.3.2.2 调用 类名:静态函数名(参数表);对象.静态函数名(参数表);指向对象的指针-静态函数名(参数表);例如:class Small static int object;public:Small()object+;static int get_n()return object;,Small()object-;int Small:object=0
5、;int main()int n;n=Small:get_n();/3.3.3 全局、静态局部类对象 3.3.3.1 局部静态类对象 在函数或复合语句内,用static关键字定义的对象。例如:int fun()static Data(1,89.0);return 0;代码执行过程中第一次遇到该对象定义时,构造函数被调用,程序运行中仅调用一次;在程序运行结束前,调用析构函数,也只调用一次。例如:,class demo public:demo()cout”object constructorn”;demo()cout”object destructor n”;void fun()static de
6、mo d1;int main()coutmain startn;fun();coutagainn;fun();输出:main start coutmain endn;object constructor again main end object destructor,3.3.3.2 全局类对象 在函数外定义的对象。构造函数在main函数执行前被调用,析构函数在程序运行结束前调用。例如:class demo public:demo()coutobject constructor n;demo()coutobject destructor n;int main()coutmain startn;
7、coutmain endn;return 0;输出:object constructor static demo d1;main start main end object destructor,3.4 友元3.4.1 友元函数3.4.1.1友元函数的声明 允许一个类授权其它的函数或类访问它的非公有成员。友元声明以friend关键字开头,只能出现在类的定义中。友元不是类的成员,不受访问说明符的影响。一般将类中所有友元关系的声明放在类头之后。语法:friend 数据类型 函数名(参数标);3.4.1.2 友元函数的参数 成员函数由对象调用,系统传递this指针使其可以访问对象的成员。友元函数没有
8、this指针,要访问对象的成员,必须将要访问的对象作为参数传递。访问类对象的成员必须加上对象名和成员访问运算符。例如:class Data friend void get_val(Data,public:Data(int a,float f)num=a;score=f;Data()num=0;score=0.0;void print();void Data:print()coutnum“n”score“n”;void set_val(Data,3.4.2 友元类3.4.2.1 友元类的声明 在类的定义体内声明 语法:friend class 类名;友元类的所有成员函数都可以访问授权类的成员。友
9、元关系是单向的,A是B的友元,但B不是A的友元。例如:class Data friend class Teacher;int num;float score;public:Data(int a,float f)num=a;score=f;Data()num=0;score=0.0;void print();,class Teacher public:void set_data(Data 注意:Teacher类的定义应在Data类之后。3.4.2.2 类的成员函数作为友元函数 若授权类的友元类中只有一个成员函数要访问授权类的成员,可以只将该成员函数作为授权类的友元函数。,友元类必须在授权类之前定
10、义,但是授权类要在友元类之前作前向声明。只有当一个类的定义已经被看到时,其成员函数才能被声明为另一个类的友元。例如:class Data;/声明 class Teacher public:void set_data(Data,第4章 运算符重载4.1 算术运算符+、-可以对任意基本类型进行“+”运算,例如:3+4.7、5+a,c 语言本身已经重载了该运算符,所以它能够用于int、float、double和其他内部定义类型的变量.如果希望“+”运算可以应用在类对象上,如:data1+data2,需要以函数的形式重新定义“+”运算执行的行为,称为运算符的重载。注意:只能对用户自定义的数据类型重载运
11、算符,即运算符重载函数的参数至少有一个必须是类的对象或者是对类的对象的引用。运算符重载实际是定义函数,调用函数时实参不是出现在圆括号内,而是在运算符的旁边,函数名是由关键字operator和其后要重载的运算符符号组成的。重载不能改变运算符的优先级、结合性。重载不能改变运算符操作数的个数和运算符本身的含义。不能创建新的运算符,只有现有的运算符才能被重载。4.1.1 作为普通(友元)函数重载 定义:数据类型 operator+(参数表)例如:class demo friend demo operator+(demo,int a;float b;public:demo(int x,float y)a
12、=x;b=y;demo operator+(demo 调用:对象+对象 例如:,demo demo1(2,3.2),demo2(1,4.6),demo3;demo3=demo1+demo2;/相当于demo3=operator+(demo1,demo2);demo operator+(demo/不能写成demo2=5+demo1;demo operator+(demo&d1,int x),希望实现调用:整数+对象 demo operator+(int x,demo 4.1.2 作为成员函数重载 表示该类对象与另一个操作数进行运算。该类对象作为操作数1。成员函数将指向调用成员函数的类对象的thi
13、s指针作为第一个参数,所以重载运算符函数需要的参数个数为运算符的操作数个数-1。调用运算符重载函数时,运算符左侧的操作数为调用成员函数的该类对象,右侧的操作数为传递给成员函数的参数。例如:,class demo int a;float b;public:demo(int x,float y)a=x;b=y;demo operator+(demo,希望实现调用:对象+整数 demo demo:operator+(int x)demo temp(0,0.0);temp.a=a+x temp.b=b+x;return temp;例如:demo demo1(2,3.2),demo2;demo2=dem
14、o1+5;/相当于demo2=demo1.operator+(5);/不能写成demo2=5+demo1;希望实现调用:整数+对象,不能定义成成员函数。如果运算符的左侧操作数不是类类型而是其它类型,重载运算符函数只能作为友元函数。4.2 运算符+、-4.1.1 作为普通(友元)函数重载 前置运算符:,定义:数据类型 operator+(参数表);例如:class demo friend demo/相当于operator+(demo1),后置运算符:需要增加一个额外的参数 例如:demo operator+(demo,public:demo(int x,float y)a=x;b=y;demo,
15、调用:demo demo1(2,3.2);5+demo1+;/相当于demo1.operator+(int)4.3 赋值运算符=的重载 运算符()、-,或者任何赋值运算符重载函数必须声明为类的一个成员函数。赋值运算符重载用于“=”两侧的对象都已经存在时,一个类对象向该类的另一个对象赋值。一般在对象的数据成员是指针时用来进行深层复制。例如:demo d1(1,4.2);/构造函数 demo d2=d1;/拷贝构造函数 d3=d2;/赋值 注意:确保没有将对象复制给它自身 重新使用被赋值对象中的资源或删除它 从源对象上复制内容到目的对象 例如:class Tstring char*str;,int
16、 len;public:Tstring(const char*p);Tstring()delete str;Tstring(const Tstring,赋值运算符重载也可以用于为一个类对象赋以不是该类类型的值。例如希望实现如下赋值:Tstring car(“benz”);car=“bmw”;在类定义中增加成员函数:Tstring,4.4 下标运算符 的重载 可以重载用于检查数组的下标是否越界 定义:operator(int index)调用:对象下标 出现在赋值运算符左侧,应该返回左值(指针、引用),出现在赋值运算符右侧,应该返回元素的值,但是函数只有一种返回类型,只有返回引用可以作为左值。例
17、如:class intarray int size;int*ip;public:intarray(unsigned maxsize)size=maxsize;ip=new intsize;intarray()delete ip;,int,4.5 成员访问运算符-的重载 赋予类类型类似指针的行为 定义:数据类型 operator-()调用:对象-成员,相当于:(对象operator-()-成员 注意:对-的重载必须返回指向类对象的指针-后的成员必须是返回的指针可以访问的成员 在返回的指针上再应用-以访问该成员。例如:,class foo public:int m;class z public:f
18、oo f;foo*operator-()return/可用于访问对象成员的成员 4.6 函数调用运算符()的重载 重载了()运算符的对象称为function object,可作为函数来使用,定义:数据类型 operator()(参数表)调用:类对象(参数表)例如:class lessthan int val;public:lessthan(int x)val=x;bool operator()(int value)const;bool lessthan:operator()(int value)const return valueval;int main()lessthan it(10);in
19、t a=5;if(it(a)cout”less than”;return 0;,例如:class absint public:int operator()(int value)int result=valuea;coutitabs(a);return 0;4.7 用户定义的转换 隐式调用,4.7.1 构造函数作为转换函数 只有一个基本类型参数(可以还有其它缺省参数)的构造函数,可以作为类型转换构造函数,实现转换:基本类型类类型 使用构造函数执行隐式转换时,构造函数参数类型不必与被转换值的类型完全一致,编译器会在调用构造函数执行用户定义的转换之前,对实参应用标准转换。例如:class demo
20、friend demo operator+(demo/4.2intdemo,类A的构造函数将类B的对象(或引用)作为它的单个参数,可以作为类型转换构造函数,实现转换:B类类型A类类型 例如:class B public:B();class A public:A(B 调用构造函数A(b1)把b1转换成A类型的值。编译器调用构造函数创建一个A类型临时对象,将临时对象的值传递给fun()函数。,4.7.2 类型转换运算符重载(转换函数)定义:operator 类型()实现类类型和转换函数中指定的类型之间的转换注意:转换函数不允许定义返回类型,但必须有返回值。只能定义成类的成员函数,转换函数中指定的类
21、型可以是内置类型、类类型。例如:class demo demo operator+(demo,int main()demo d1(4,7.5);int a=5+d1;/调用d1.operator int()将d1intdouble f=d1+3.9;/调用d1.operator int()将d1intdouble couta”n”f”n”;4.7.3 构造函数和转换函数的相互影响 转换函数执行后,可以用标准转换把转换函数的结果转换成目标类型;在构造函数执行转换之前,可以用标准转换把要转换的值转换成构造函数参数的类型。现类型目标类型转换序列:标准转换用户定义的转换标准转换 当不只一个转换序列可以被应用时,编译器必须选择最好的序列执行转换。标准转换成为选择的依据。若所有的转换都一样好,则出现二义性。例如:class demo int a;public:,demo(int x=0)/intdemoa=x;operator int()return a;operator float()return a;int main()demo d1(3);long v=d1;/调用d1.operator int()将d1intlong/调用d1.operator float()将d1floatlong,
链接地址:https://www.31ppt.com/p-4008766.html