C++ 共享数据(一)静态

来源:互联网 发布:域名询价 编辑:程序博客网 时间:2024/06/04 19:54

目录
1、       为何用静态数据成员
2、       静态数据成员
3、       静态成员函数
4、       静态成员函数何时使用?

----------------------------------------------------------------------------------------------------

一、为何用静态数据成员

C++用Const保护数据对象不被修改,在实际中还需要共享数据,C++怎么提供数据共享机制?

 C++静态成员和友元都能实现对象之间、类之间的数据共享。

二、静态数据成员

静态数据成员定义格式:

tatic  类型  数据成员名

a.由于一个类的所有对象共享静态数据成员,所以不能用构造函数为静态数据成员初始化,只能在类外专门对其进行初始化。

格式:

  数据类型   类名::静态数据成员名=初值;

        如果程序未给静态数据成员赋初始值,则编译系统自动用0为它赋初值。

   b.即可以用对象名引用静态成员,也可以用类名引用静态成员。

c.静态数据成员在对象外单独开辟内存空间,只要在类中定义了静态成员,即使不定义对象,系统也为静态数据成员分配内存空间,可以被引用。

d.在程序开始时为静态成员分配内存空间,直到程序结束才释放内存空间。

e.静态数据成员作用域是它的类的作用域(如果在一个函数内定义类,它的静态数据成员作用域就是这个函数),在引用范围内可以用“类名::静态成员名”的形式访问静态数据成员。

综合实例:

/*********************************************************** 文件名称: TBox.cpp* 内容摘要: 长方体的体积:引用静态数据成员***********************************************************/#include "stdafx.h"#include "iostream"using namespace std;class TBox{public:TBox( int w = 0, int h = 0) : width(w), heigth(h){}int Volume() const;public:static int length;private:int width, heigth;};int TBox::length = 100; <span style="white-space:pre"></span>//为静态数据成员赋值int TBox::Volume() const{return length*width*heigth ;}int _tmain(int argc, _TCHAR* argv[]){TBox box1(5, 5);TBox box2(10, 10);TBox box3(20, 20);cout << "TBox的高为:" << TBox::length << endl;cout << "box1的高为:" << box1.length << endl;cout << "box2的高为:" << box2.length << endl;cout << "box3的高为:" << box3.length << endl << endl;cout << "box1的体积为:" << box1.Volume() << endl;cout << "box2的体积为:" << box2.Volume() << endl;cout << "box3的体积为:" << box3.Volume() << endl;return 0;}

三、静态成员函数

C++提供静态成员函数,用它访问静态数据成员,静态成员函数不属于某个对象而属于类。

类中的非静态成员函数可以访问类中的所有数据成员;

而静态成员函数可以直接访问类的静态成员,不能直接访问非静态成员。

静态成员函数定义格式:

static 类型  成员函数(形参表){…….}


调用公有静态成员函数格式

类名::成员函数(实参表)


静态成员函数不带this指针,所以必须用对象名和成员运算符.访问非静态成员;

而普通成员函数有this指针,可以在函数中直接引用成员名。

综合实例:

/********************************************************* 文件名称: Student.cpp* 内容摘要: 求学生生成绩的平均分******************************************************************/#include "stdafx.h"#include "iostream"#include "string"using namespace std;class Student{public:Student(int nu = 001, string na = " ", double s = 0) :num(nu), name(na), score(s){}void Total();//普通成员函数 求所有学生的总成绩,和总人数static double Average();<span style="white-space:pre"></span>//静态成员函数,求平均分private:int num;string name;double score;static double sum;//静态数据成员,记录所有学生的总分数static int count;//静态数据成员,记录学生总数};double Student::sum = 0;int Student::count = 0;void Student::Total(){sum = sum + score;//统计总分数count++;//统计个数}double Student::Average(){return sum / count;}int _tmain(int argc, _TCHAR* argv[]){Student stu[3] = {Student(001, "张飞", 80),Student(002, "关羽", 90),Student(003, "刘备", 100)};for (int i = 0; i < 3; i++){stu[i].Total();}cout << "学生的平均成绩为:" << Student::Average() << endl;return 0;}

四、静态成员函数何时使用及好处?

转自http://blog.sina.com.cn/s/blog_640531380100sgsz.html

       所有的好处都是基于:它跟类的实例无关,只跟类有关,不需要this指针。


(1)可以实现某些特殊的设计模式:如Singleton;

(2)由于没有this指针,可以把某些系统API的回调函数以静态函数的形式封装到类的内部。因为系统API的回调函数通常都是那种非成员函数(孤立函数),没有this指针的。

       比如你可以在类的内部写一个线程函数供CreateThread创建线程用,如果没有静态函数,那么这种回调函数就必须定义成全局函数(非静态成员函数指针无法转换成全局函数指针),从而影响了OO封装性

(3)可以封装某些算法。

       比如数学函数,如lnsintan等等,这些函数本就没必要属于任何一个对象,所以从类上调用感觉更好,比如定义一个数学函数类Math,调用Math::sin(3.14);如果非要用非静态函数,那就必须:
       Math   math;

       math.sin(3.14);
行是行,只是不爽:就为了一个根本无状态存储可言的数学函数还要引入一次对象的构造和一次对象的析构,当然不爽。而且既然有了对象,说不得你还得小心翼翼的定义拷贝构造函数、拷贝赋值运算符等等,对于一些纯算法的东西显然是不合适的。

(4)总之,从OOA/OOD的角度考虑,一切不需要实例化就可以有确定行为方式的函数都应该设计成静态的。


      
以上只是一些基本的考虑,并不是绝对的。绝对东西的只有一点:“静态函数不需要实例化就可以被调用,不会也不可以调用或操纵非静态成员”。记住这一点,那么实际编程中何时需要用,何时适合用,自然就更容易作出决定了。




0 0
原创粉丝点击