首页 > 编程知识 正文

引用静态数据成员,指针和数组名访问数组的联系

时间:2023-05-04 09:03:48 阅读:61205 作者:3854

转载来源: https://blog.csdn.net/computer _ qld ZC/article/details/29235111

C的静态静态数据成员和静态成员函数应该会困扰大家,似乎在就业公司的面试中也经常出现。 我自己也深有体会。 在学习C的过程中,静态总是觉得很麻烦,但又是必须要理解的,所以今天我要坐在静态数据成员和静态成员函数上总结一下。

一、静态数据成员1.静态数据成员怎么去定义?

在类中声明静态数据成员很简单,用静态关键字表示如下

class Test{private://静态数据成员静态int a; (; a是静态数据成员。 类中可以声明,但不能定义。

要定义和初始化静态数据成员,必须在类外部定义,即在全局范围内定义。 如果定义不提供初始值,则缺省初始值为0

class Test{public:int GetA () const{return a; }私有://静态数据成员静态Int a; (; //int Test:a; 如果这样定义而不给出初始值,则初始值为零的int Test:a=1; #include iostreamint main () {Test T; std:cout T.GetA () std:endl; }用全局范围定义,不要在类中定义。

即使类中没有对象,静态数据成员也可以访问。 静态成员可以独立访问,而不依赖于对象的创建

此外,不要尝试在头文件中定义(初始化)静态数据成员。 很多情况下,这样做会引起重复定义的错误。 附加#ifndef #define #endif或#pragmaonce也不行。

2.静态数据成员被类的所有对象共享,包括该类的派生类对象,基类对象和派生类对象共享基类的静态数据成员

a )静态数据成员不属于任何对象,类的静态数据成员的存在不取决于任何类对象的存在,静态数据成员由类的所有对象共享。 例子如下。

class Base{public://静态数据成员静态int a; (; class derived :公共基{ }; //int Test:a; 这样定义,如果不给出初始值,则初始值为零的int Base:a; #include iostreamint main () {Base B; 导向d; 乙. A; STD :3360 coutb.astd 33603360 endl; D.a; STD :3360 coutd.astd 33603360 endl; }打印结果如下。

从打印结果中可以看到,派生类对象和基类对象是共享基类的静态数据成员,基类中的所有对象也共享此静态数据成员。 此外,静态数据成员必须在全局范围中定义。 可以给出初始值,也可以不给出初始值。 如果不提供初始值,静态数据成员将具有默认值。

3.静态数据成员可以作为成员函数的默认形参,而普通数据成员则不可以

a :别说太多,直接看例子就知道了!

class Test{public://静态数据成员静态int a; int b; voidfun_1(intI=a ); //正确的voidfun_2(intI=b ); //报告错误;4.静态数据成员的类型可以是所属类的类型,而普通数据成员则不可以。普通数据成员的只能声明为 所属类类型的 指针或引用

答:这个也别说,直接看例子能明白什么意思!

class Test{public://静态数据成员静态测试a; //正确的测试b; //报告错误的Test *pTest; //正确的Test m_Test; //正确的静态测试*静态对象; //正确;5.静态数据成员在const函数中可以修改,而普通的数据成员是万万不能修改的哈!

答:让我们来看看例子

类测试{ public : test () :b(0) }//静态数据成员static int a; //正确的int b; void test () const{a ) a; B; //const; int Test:a; 如果const已限定,则当前this指针指向的对象为const,但静态数据成员不属于任何类中的对象,并且会被类中的所有对象更改。 因此,可以更改this指针,因为它不限定静态数据成员。

二、静态成员函数静态成员函数的声明也很简单。 在类的成员函数前加上静态关键字就可以了。 与静态成员一样,静态成员函数也属于类。 它不属于任何对象。 调用静态成员函数时应该使用类名和域运算符“”。 当然,也可以使用对象调用操作,但这样的操作并不意味着静态成员函数属于此对象,而只是将

对象共享而已,这样也就决定了静态成员函数中是不能访问本类中的非静态数据成员的,它是不能访问非静态数据成员的,在c++中静态成员函数主要用来访问静态数据成员而不访问非静态数据成员

1.静态成员函数不能调用非静态成员函数,但是反过来是可以的

2.静态成员函数没有this指针,也就是说静态成员函数不能使用修饰符(也就是函数后面的const关键字)

3.静态成员函数的地址可用普通函数指针储存,而普通成员函数地址需要用 类成员函数指针来储存。

总结:其实声明为静态,不论是静态数据成员还是静态成员函数,它们都是不依赖于对象而存在的,类在定义后并不分配存储空间,而是在定义类的对象的时候才分配存储空间,相反静态的数据成员和静态的成员函数是已经在内存中开辟了内存空间了,所以静态数据成员可以独立的访问在任何类对象没有建立起来都可以访问,并且静态成员函数不可以调用非静态成员函数,因为非静态成员函数只有在类对象建立以后才可以调用,相反则是可以的。我觉得当对某个判断产生怀疑的时候应该去测试,只有验证了才知道是不是对的哈!

为了能更好阐释静态数据成员和静态成员函数,然后在网上搜了博客,感觉有些例子不错(因找不到最初的出处,所以无法注明请原作者谅解),所以就拿来给大家参考一下哈!

关于玩篮球的例子很能明显解释静态数据成员和静态成员函数到底是怎么回事

你们班里面有10个人(10个比如高一一班的对象),体育老师分给你们一个篮球(静态成员函数),你们每个人都带了一个篮球(非静态成员数),你们都很小气,自己的球只能自己拍,要是5对5打比赛,那就只能用那个静态的篮球了(每个人都可以拿来用,但是带来的影响是对全体的)。因此,我可以说那个篮球是高一一班的成员。所以也就是说:静态成员函数是类的成员函数(因为高一二班就不能拿来玩),但是这个篮球最后还是要还给老师的,任何私人不得占有。希望这样你能明白,其实在内存空间里面说白了静态的成员的内存是唯一的一份,就是yqddx在类外声明他时开辟的,但是非静态函数的空间分配是在你实例化对象时创建的。

为了使大家更好的理解这两个概念,还是老样子用代码来说明上面文字说明的这一切哈!

关于学生类的例子

//定义Student类#include <iostream>class Student {public://定义构造函数Student(int n,int a,float s):num(n),age(a),score(s){ } void total();//声明静态成员函数static float average(); private:int num;int age;float score;//静态数据成员,累计学生的总分static float sum; //静态数据成员,累计学生的人数static int count; };//在全局作用域对静态数据成员初始化,如果不赋予初值,则使用其默认值零float Student::sum; int Student::count;//定义非静态成员函数void Student::total() {//累加总分sum+=score;//累计已统计的人数count++; }//定义静态成员函数float Student::average() {return(sum/count);}int main(){Student stud[3]={ //定义对象数组并初始化Student(1001,18,70),Student(1002,19,78),Student(1005,20,98)};int n;std::cout<<"please input the number of students: "; //输入需要求前面多少名学生的平均成绩std::cin>>n; //调用3次total函数for(int i=0;i<n;i++){stud[i].total();}//调用静态成员函数std::cout<<"the average score of "<<n<<" students is "<<Student::average( )<<std::endl;return 0;}

打印输出如下:

 

对上面的代码做以下说明:

首先,在主函数中定义了对象数组,存放每个学生的编号、年龄和成绩,其中sum和count是要累计所有学生的总成绩和总的学生人数,我们定义成了静态数据成员,在学生类的成员函数中,我们定义了普通的total成员函数,用来计算所有学生的总成绩和总的学生人数,另外,定义了静态成员函数average,学生类的设计大概如此

在全局作用域对类中静态数据成员进行了定义,但未赋予初值,这意味着我们采用其默认值。

在类的普通成员函数toal中可以引用静态数据成员sum和count,可见类的所有成员函数都可以引用类的静态数据成员。

在类的静态成员函数average中,只能引用类的静态数据成员,不能引用非静态数据成员。

在主函数中我们调用类的非静态成员函数时只能通过类对象来调用,如stu[i].total,但是对于静态成员函数可以直接通过类名+作用域符号来调用,如

Student::average。

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。