实验八 静态数据成员和静态函数成员
C++语言中静态数据成员和静态成员函数的研究

电脑知识与技术电脑知识与技术研究开发1引言类是类型而不是数据对象,每个类对象都是该类数据成员的拷贝。
然而,在某些情况下需要让类的所有对象在类的范围内共享某个数据,例如一个类的多个对象需要根据同一个数据的状态来决定下一个动作时,这时就会想到利用全局变量,但全局变量在类的外面,既不安全,又影响了重用性,一旦程序庞大,维护量就急剧上升,使用静态数据成员,就可以解决这个问题,同时也节省了空间和构造对象时的时间。
又不破坏面向对象的封装性,静态成员函数的使用也给程序设计带来很大的好处。
2类静态数据成员的定义及声明方法在一个类中,如果它的数据成员使用关键字static进行修饰,这样的成员称为静态数据成员。
静态数据成员提供的是类的所有对象共享的信息,无论建立多少个该类的对象,都只有一个静态数据的拷贝。
尽管静态数据成员看起来有些象全局变量,但它是具有类作用域的。
静态数据成员可以是公有的、私有的或受保护的。
静态数据成员必须在文件作用域内初始化,并且只在文件范围中初始化一次。
在数据成员声明的最前面加上系统关键字static就成了静态数据成员,例如:classzy{public:staticintdata;};3类静态数据成员的访问类的静态数据成员是在编译阶段(而不是运行阶段)时进行空间的分配和初始化的,所以,类的静态数据成员是属于类的,而不是属于某个具体对象的,它们被该类的所有对象共享,被存储在一个公用的内存中,即使还没有建立对象,静态数据成员就已经存在,从而类的public静态数据成员既可以利用二元作用域运算符通过类名访问,也可以通过类的任何对象直接访问,实际上,通过对象名引用静态数据成员时,C++系统只关心静态数据成员的类类型;类的private和protected静态数据成员应通过类的public成员函数或通过类的友元访问。
3.1通过类名访问静态数据成员即使类没有一个对象,其静态数据成员依然存在,所以就可以访问,一般来说,通过类名访问静态数据成员,比使用对象名访问静态数据成员要好,因为静态数据成员不是对象的成员,而是属于类的。
实验8-常数据成员、常成员函数

#include <iostream.h> class Rectangle { public: Rectangle(int a,int b)//2个参数的构造函数Rectangle { width=a; length=b; }//负责对对象的宽和长数据成员初始化 int Area()//求矩形的面积 { return width*length; } int Periment()//求矩形的周长 { return 2*(width+length); } void Changesize(int a,int b)//改变矩形的宽和长 { width=a; length=b; } void Print();//负责打印求的的面积和周长 private: int width,length; }; void Rectangle::Print() { cout<<"AREA="<<Area()<<endl; cout<<"PERIMENT="<<Periment()<<endl; } void main() { Rectangle r(5,8);//定义对象r 初始化 r.Print(); r.Changesize(3,9);//调用对象r的成员函数Changesize改变宽和长 r.Print(); }
《教材》第六章例题(lt): 6.9 (lt6.9.cpp) 6.10 (lt6.5之:
2(xt6.5-2.cpp); 3(xt6.5-3.cpp);
2、编程实现一个简单的计算器。要求从键盘上输入两 个浮点数,计算出它们的加、减、乘、除运算的结 果。
常成员函数常数据成员什么是常数据成员成员函数指针什么是成员函数静态成员函数成员函数类的静态成员函数cstring成员函数static成员函数
类的static成员函数与普通成员函数的区别

类的static成员函数与普通成员函数的区别成员函数:⽆论静态函数还是⾮静态函数,都是属于类的(这⼀点与数据成员的静态⾮静态不同),对象并不拥有函数的拷贝.两者的区别在于:⾮静态的函数由类对象(加.或指针加->;)调⽤,这时将向函数传递this指针.⽽静态函数由类名(::)(或对象名.)调⽤,但静态函数不传递this指针,不识别对象个体,所以通常⽤来对类的静态数据成员操作.程序最终都将在内存中执⾏,变量只有在内存中占有⼀席之地时才能被访问。
类的静态成员(变量和⽅法)属于类本⾝,在类加载的时候就会分配内存,可以通过类名直接去访问;⾮静态成员(变量和⽅法)属于类的对象,所以只有在类的对象产⽣(创建类的实例)时才会分配内存,然后通过类的对象(实例)去访问。
在⼀个类的静态成员中去访问其⾮静态成员之所以会出错是因为在类的⾮静态成员不存在的时候类的静态成员就已经存在了,访问⼀个内存中不存在的东西当然会出错。
C++会区分两种类型的成员函数:静态成员函数和⾮静态成员函数。
这两者之间的⼀个重⼤区别是,静态成员函数不接受隐含的this⾃变量。
所以,它就⽆法访问⾃⼰类的⾮静态成员。
静态数据成员在类中,静态成员可以实现多个对象之间的数据共享,并且使⽤静态数据成员还不会破坏隐藏的原则,即保证了安全性。
因此,静态成员是类的所有对象中共享的成员,⽽不是某个对象的成员。
使⽤静态数据成员可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储⼀处,供所有对象共⽤。
静态数据成员的值对每个对象都是⼀样,但它的值是可以更新的。
只要对静态数据成员的值更新⼀次,保证所有对象存取更新后的相同的值,这样可以提⾼时间效率。
静态数据成员的使⽤⽅法和注意事项如下:1、静态数据成员在定义或说明时前⾯加关键字static。
2、静态成员初始化与⼀般数据成员初始化不同。
静态数据成员初始化的格式如下:<数据类型><类名>::<静态数据成员名>=<值>这表明:(1) 初始化在类体外进⾏,⽽前⾯不加static,以免与⼀般静态变量或对象相混淆。
C++程序设计教程08Chapter08

本章习题
1、数据定义为全局变量,破坏了数据的 ___________;较好的解决办法是将所要共享 的数据定义为类的___________。 2、静态数据成员和静态成员函数可由 ___________函数访问 3、___________和___________统称为友元 4、友元的正确使用能提高程序___________, 但破坏了类的封装性和数据的隐蔽性
小结
本章需要重点理解静态成员的基本概念, 本章需要重点理解静态成员的基本概念,掌握 静态数据成员和静态成员函数的概念和使用方 法。 了解友元的必要性 掌握如何使用友元函数和友元类。 掌握如何使用友元函数和友元类。
本章习题
一、选择题 1、关于静态数据成员,下面说法错误的是 、关于静态数据成员,下面说法错误的是___________。 。 A) 使用静态数据成员,实际上是为了消除全局变量。 使用静态数据成员,实际上是为了消除全局变量。 B) 可以使用 “ 对象名 静态成员 ” 或者 “ 类名 静态成员 ” 来访问静态数据成员 。 可以使用“对象名.静态成员 或者“类名::静态成员 来访问静态数据成员。 静态成员” 静态成员” C) 静态数据成员只能在静态成员函数中引用。 静态数据成员只能在静态成员函数中引用。 D) 所有对象的静态数据成员占用同一内存单元。 所有对象的静态数据成员占用同一内存单元。 2、下面的函数中,静态成员函数不能访问的是 、下面的函数中,静态成员函数不能访问的是___________ A) 静态数据成员 B) 静态成员函数 C) 类以外的函数和数据 D) 非静态数据成员 3、在类的定义中,引入友元的原因是 、在类的定义中,引入友元的原因是___________ A) 提高效率 B) 深化使用类的封装性 C) 提高程序的可读性 D) 提高程序的可读性 4、友元类的声明方法是:___________ 、友元类的声明方法是: A) friend class <类名 类名>; B) youyuan class <类名 类名>; 类名 类名 C) class friend <类名 类名>; D) friends class <类名 类名> 类名 类名
C#中的静态成员、静态方法、静态函数之说.doc

C#中的静态成员、静态方法、静态函数之说.docC#静态成员I静态方法I静态构造函数一、静态成员(static)(1)静态成员属于类所有,非静态成员属于类的实例所有。
⑵ 每创建一个类的实例,都会在内存中为非静态成员新分配一块存储;非静态成员属于类所有,为各个类的实例所公用,无论类创建了多少实例,类的静态成员在内存中只占同一块区域。
二、静态方法(1)静态方法属于类所有,类实例化前即可使用。
(2)非静态方法可以访问类中的任何成员,静态方法只能访问类中的静态成员。
因为静态方法在类实例化前就可以使用,而类中的非静态变量必须在实例化之后才能分配内存,这样,静态方法调用时无法判断非静态变量使用的内存地址。
所以无法使用?而静态变量的地址对类来说是固定的,故可以使用。
三、静态构造函数(1)用于对静态字段、只读字段等的初始化。
⑵添加static关键字,不能添加访问修饰符,因为静态构造函数都是私自有的。
⑶ 类的静态构造函数在给定应用程序域中至多执行一次:只有创建类的实例或者引用类任何静态成员才激发静态构造函数?(4)静态构造函数是不可继承的,而且不能被直接调用。
⑸ 如果类中包含用来开始执行的Main方法,则该类的静态构造函数将在调用Main方法之前执行。
任何带有初始值设定项的静态字段,则在执行该类的静态构造函数时,先要按照文本顺序执行那些初始值设定项。
(6)如果没有编写静态构造函数,而这时类中包含带有初始值设定的静态字段,那么编译器会自动生成默认的静态构造函数。
(7)无参数的构造函数可以与静态构造函数共存。
尽管参数列表相同,但一个属于类,一个属于实例,所以不会冲突。
MSDN对静态构造函数的解释:静态构造函数用于初始化任何静态数据,或用于执行仅需执行一次的特定操作。
在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数。
静态构造函数具有以下特点:⑴静态构造函数既没有访问修饰符,也没有参数。
(2)在创建第一个实例或引用任何静态成员之前,将自动调用静态构造⑶函数来初始化羹。
C++中静态成员函数与非静态成员函数的区别

C++中静态成员函数与⾮静态成员函数的区别静态成员函数与⾮静态成员函数的区别数据成员:静态数据成员是类的⼀部分,为类的所有实例共享(静态区);⾮静态数据成员,类的每个实例都有⼀份拷贝(动态区)。
静态数据成员的访问:静态数据成员是类的⼀部分,在产⽣任何实例之前已经存在,通过类名::静态成员变量名访问。
函数成员(都在代码区):静态函数成员与⾮静态函数成员都为类所有,对象并不存在函数的拷贝。
静态成员函数和⾮静态成员函数的根本区别在于⾮静态函数由对象名.或者对象指针->调⽤,调⽤时编译器会向函数传递this指针;静态成员函数则有类名::或者对象名.调⽤,编译器不向函数传递this指针,不识别对象个体,经常⽤来操作类的静态数据成员,要访问类的⾮静态成员可以通过对象来实现。
内存⾓度分析:类的静态成员(数据成员和函数成员)为类本⾝所有,在类加载的时候就会分配内存,可以通过类名直接访问;⾮静态成员(数据成员和函数成员)属于类的实例所有,所以只有在创建类的实例的时候才会分配内存,并通过实例去访问。
注意:类的静态数据成员是静态存储,它是静态⽣存周期,必须进⾏初始化。
注意:静态数据成员的初始化在类体外进⾏,前⾯不加static以免与⼀般静态变量或者对象混淆。
静态成员函数访问⾮静态成员报错:类的静态成员在类加载的时候就已经分配内存,⽽此时类的⾮静态成员尚未分配内存,访问内存中不存在的东西⾃然会出错。
例⼦:#includeusing namespace std;class Test{public:Test(int a){ A = a; ++B;}static void smf(Test tt);private:int A;static int B;};void Test::smf(Test tt){cout << "tt.A : " << tt.A << endl; //静态成员函数中通过对象来引⽤⾮静态成员cout << "Test::B : " << Test::B << endl;cout << "tt.B : " << tt.B << endl;}int Test::B = 0; //静态数据成员初始化的格式<数据类型><类名>::<静态数据成员名>=<值>int main(){Test t1(100);Test t2(200);Test::smf(t1);Test::smf(t2);//静态成员函数调⽤时不⽤对象名system("pause");return 0;}感谢阅读,希望能帮助到⼤家,谢谢⼤家对本站的⽀持!。
静态函数 静态数据成员与静态成员函数 为什么虚函数必须是非静态成员函数 构造函数能为static吗

静态函数静态数据成员与静态成员函数为什么虚函数必须是非静态成员函数构造函数能为static吗?2009-07-05 14:27静态函数用static声明的函数是静态函数。
静态函数可以分为全局静态函数和类的静态成员函数。
Static关键字在类中,用static声明的成员变量为静态成员变量,它为该类的公用变量,在第一次使用时被初始化,对于该类的所有对象来说,static成员变量只有一份。
用static声明的方法是静态方法,在调用该方法时,不会将对象的引用传递给它,所以在static方法中不可访问非static的成员。
静态方法不再是针对于某个对象调用,所以不能访问非静态成员。
可以通过对象引用或类名(不需要实例化)访问静态成员C++类静态数据成员与类静态成员函数函数调用的结果不会访问或者修改任何对象(非static)数据成员,这样的成员声明为静态成员函数比较好。
且如果static int func(....)不是出现在类中,则它不是一个静态成员函数,只是一个普通的全局函数,只不过由于static的限制,它只能在文件所在的编译单位内使用,不能在其它编译单位内使用。
静态成员函数的声明除了在类体的函数声明前加上关键字static,以及不能声明为const或者volatile之外,与非静态成员函数相同。
出现在类体之外的函数定义不能制定关键字static。
静态成员函数没有this指针。
在没有讲述本章内容之前如果我们想要在一个范围内共享某一个数据,那么我们会设立全局对象,但面向对象的程序是由对象构成的,我们如何才能在类范围内共享数据呢?这个问题便是本章的重点:声明为static的类成员或者成员函数便能在类的范围内共同享,我们把这样的成员称做静态成员和静态成员函数。
下面我们用几个实例来说明这个问题,类的成员需要保护,通常情况下为了不违背类的封装特性,我们是把类成员设置为protected(保护状态)的,但是我们为了简化代码,使要说明的问题更为直观,更容易理解,我们在此处都设置为public。
C++类静态成员与类静态成员函数=

C++类静态成员与类静态成员函数当将类的某个数据成员声明为static时,该静态数据成员只能被定义一次,而且要被同类的所有对象共享。
各个对象都拥有类中每一个普通数据成员的副本,但静态数据成员只有一个实例存在,与定义了多少类对象无关。
静态方法就是与该类相关的,是类的一种行为,而不是与该类的实例对象相关。
静态数据成员的用途之一是统计有多少个对象实际存在。
静态数据成员不能在类中初始化,实际上类定义只是在描述对象的蓝图,在其中指定初值是不允许的。
也不能在类的构造函数中初始化该成员,因为静态数据成员为类的各个对象共享,否则每次创建一个类的对象则静态数据成员都要被重新初始化。
静态成员不可在类体内进行赋值,因为它是被所有该类的对象所共享的。
你在一个对象里给它赋值,其他对象里的该成员也会发生变化。
为了避免混乱,所以不可在类体内进行赋值。
静态成员的值对所有的对象是一样的。
静态成员可以被初始化,但只能在类体外进行初始化。
一般形式:数据类型类名::静态数据成员名=初值注意:不能用参数初始化表对静态成员初始化。
一般系统缺省初始为0。
静态成员是类所有的对象的共享的成员,而不是某个对象的成员。
它在对象中不占用存储空间,这个属性为整个类所共有,不属于任何一个具体对象。
所以静态成员不能在类的内部初始化,比如声明一个学生类,其中一个成员为学生总数,则这个变量就应当声明为静态变量,应该根据实际需求来设置成员变量。
#include "iostream"using namespace std;class test{private:int x;int y;public:static int num;static int Getnum(){x+=5; // 这行代码是错误的,静态成员函数不能调用非静态数据成员,要通过类的对象来调用。
num+=15;return num;}};int test::num = 10;int main(void){test a;cout<<test::num<<endl; //10test::num = 20;cout<<test::num<<endl; //20cout<<test::Getnum()<<endl; //35cout<<a.Getnum()<<endl; //50system("pause");return 0;}通过上例可知: x+=5; // 这行代码是错误的静态函数成员必须通过对象名来访问非静态数据成员。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验八静态数据成员和静态函数成员
任务一:
1、了解多文件工程
本次实验需要创建一个工程,此工程由三个文件组成
1)头文件client.h ——类的声明
2)源文件client.cpp——成员函数的定义
3)源文件test.cpp——main()函数的定义
2、了解CLIENT类
本次实验的主角是CLIENT(客户机)类。
在实际生活中,计算机网络的应用模式为client/server(客户机/服务器)模式。
情况很简单,即多台客户机与一台服务器连接,服务器为客户机提供服务。
3、实验任务
1)阅读程序代码,仔细分析CLIENT类的各数据成员及函数成员,写出分析结果
2)创建多文件工程,编译并运行
3)为main()函数的各条语句增加注释
4)将数据成员ServerName改为非静态,其它类成员的静态属性不变。
修改程序代码,使客户机a连接到另一台服务器M。
(b仍与N连接)
任务二:
生成一个储蓄类CK。
用静态数据成员表示每个存款人的年利率lixi。
类的每个对象包含一个私有数据成员cunkuan,表示当前存款额。
提供一个calLiXi()成员函数,计算利息,用cunkuan乘以lixi除以12取得月息,不计复利,并将这个月息加进cunkuan中。
提供设置存款额函数set()。
提供一个静态成员函数modLiXi(),可以将利率lixi修改为新值。
实例化两个不同的CK对象saver1和saver2,结余分别为2000.0和3000.0。
将lixi设置为3%,计算一个月后和3个月后每个存款人的结余并打印新的结果。
首先定义储蓄类CK,它包含一个私有数据成员cunkuan,数据类型为double,一个静态数据成员年利率lixi,数据类型也为double;包含一个成员函数calLiXi()和一个静态成员函数modLiXi(),其中modLiXi()应含有一个表示要更改的年利率的新值的参数。
完善程序:
#include <iostream.h>
class CK{
double cunkuan;
public:
? //定义静态数据成员lixi
CK(double c){?}//构造函数
void set(double x){?}//设置存款额
? //定义静态成员函数modLiXi()
void calLiXi(int m=1);
};
//编写CK类的成员函数,并初始化静态数据成员。
void CK::calLiXi(int m)
{
double x;
x=?; //计算月利息
?; //将利息加入到存款中
cout<<cunkuan<<endl;
}
void CK::modLiXi(double x) //更改年利率
{ ? }
//初始化静态变量为0,静态变量必须初始化
?;
//主函数:实例化两个对象,将年利率更改为3%,计算并显示存款人的实际存款。
void main()
{
CK saver1(2000.0),saver2(3000.0);//实例化两个对象
? //以类名来调用静态成员函数,将年利率设为3%
cout<<"年利率为 3%时"<<endl;
cout<<"一个月后甲的存款余额为: ¥";
saver1.calLiXi();
cout<<"一个月后乙的存款余额为: ¥";
saver2.calLiXi();
saver1.set(2000.0);saver2.set(3000.0);
cout<<"三个月后甲的存款余额为: ¥";
saver1.calLiXi(3);
cout<<"三个月后乙的存款余额为: ¥";
saver2.calLiXi(3);
cout<<"-------------------------------------------"<<endl;
saver1.set(2000.0);saver2.set(3000.0);
? //以对象名来调用静态成员函数,将年利率设为6%
cout<<"年利率为 6%时"<<endl;
cout<<"一个月后甲的存款余额为: ¥";
saver1.calLiXi();
cout<<"一个月后乙的存款余额为: ¥";
saver2.calLiXi();
saver1.set(2000.0);saver2.set(3000.0);
cout<<"三个月后甲的存款余额为: ¥";
saver1.calLiXi(3);
cout<<"三个月后乙的存款余额为: ¥";
saver2.calLiXi(3);
}。