类中可以包含静态数据成员和静态函数成员,统称为静态成员默认情况下,静态成员的作用域是类范围内且是外部链接的静态成员在内存中只有一个副本,不是类对象的一部分,而是独立的对象因此,静态数据成员的声明不是定义,声明在类作用域内完成,而定义在文件作用域内完成,下面我们就来说一说关于c语言程序中的数据类型及其运算?我们一起去了解并探讨一下这个问题吧!

c语言程序中的数据类型及其运算(CC语言19)

c语言程序中的数据类型及其运算

类中可以包含静态数据成员和静态函数成员,统称为静态成员。默认情况下,静态成员的作用域是类范围内且是外部链接的。静态成员在内存中只有一个副本,不是类对象的一部分,而是独立的对象。因此,静态数据成员的声明不是定义,声明在类作用域内完成,而定义在文件作用域内完成。

不管这个类有多少个对象,静态数据成员都只有一份拷贝。静态数据成员一般用来保存整个类所有对象共享的信息。

1 静态成员变量

假设类SavingAccount专门用于存放存款帐户,它包括存户的姓名、地址、存款额、利率等成员变量:

class SavingAccount { char m_name[20]; //存户姓名 char m_addr[60]; //存户地址 double m_total; //存款额 double m_rate; //利率 … };

这家银行采用浮动利率,每个帐户的利息根据当天的挂牌利率计算。这时候如果m_rate就不适合成为每个帐号一个资料,否则每天一开市,光把所有帐户内容调出来,修改m_rate的值,就花掉不少时间。m_rate应该独立于各对象之外,成为独一无二的资料。怎样实现呢?就是声明为各对象共享的数据,使用关键字static。

对于静态成员数据:

1)在编译阶段就分配空间,对象还没有创建;

2)必须在类中声明,在类外初始化(或定义)。

由于静态数据成员要在类声明与定义时实际分配空间,因此不能在类声明中进行初始化。静态数据成员初始化在类的外部进行,且与一般数据成员初始化不同,它的格式如下:

<数据类型><类名>::<静态数据成员名>=<值>

3)归同一个类的所有对象所有,共享同一个静态变量。在为对象分配的空间中不包含静态成员所占空间。

4)有权限限制:private静态变量和 public静态变量。

private静态变量;在类(print类)外不能访问和操作。

类外访问:print::a;//erro 类外操作:print::a = 6;//erro

public静态变量;在类(print类)外可以访问和操作。

类外访问:print::a;//yes 类外操作:print::a = 6;//yes

5)const 静态成员变量

const static int a = 8;

定义静态变量 const 静态成员变量时,最好在类的内部初始化。

static 成员变量不属于对象的一部份,而是类别的一部份,所以程序可以在还没有诞生任何对象的时候就处理此种成员变量。但首先你必须初始化它。不要把static 成员变量的初始化动作安排在类别的构造式中,因为构造式可能一再被调用,而变量的初值却只应该设定一次。也不要把初始化动作安排在头文件中,因为它可能会被包含许多地方,因此也就可能被执行许多次。你应该在实作档中且类别以外的任何位置设定其初值。例如在main 之中,或全域函数中,或任何函数之外:

double SavingAccount::m_rate = 0.0075; // 设立static 成员变量的初值 void main() { ... }

为静态成员分配空间称为静态成员的定义。

但静态数据成员属于类,因此定义对象时并不为静态成员分配空间。

静态成员的定义一般出现在类的实现文件中。如在SavingAccount类的实现文件中,必须要如下的定义:

double SavingAccount::rate = 0.05;

该定义为rate分配了空间,并给它赋了一个初值0.05。

如果没有这个定义,连接器会报告一个错误。

可以通过作用域操作符从类直接调用。如: SavingAccount::rate

但从每个对象的角度来看,它似乎又是对象的一部分,因此又可以从对象引用它。如有个SavingAccount类的对象obj,则可以用:obj.rate

由于是整个类共享的,因此不管用哪种调用方式,得到的值都是相同的。

2 静态变量的调用

用类名加域作用符: print::a;

用对象名加取址符: class p1; p1.a;

3 静态成员函数

与静态变量一样,在没有创建对象前即可通过类名调用。

1)静态成员函数只能访问 "静态成员变量",不能访问普通成员变量。

2)静态成员函数的使用规则和静态成员变量一样。

3)静态成员函数也有使用权限。类外无法访问私有静态函数。

4)普通成员函数可访问"静态成员变量",也可访问"非静态成员变量"

class BufferedOutput { public: short BytesWritten() { return bytecount;} static void ResetCount() { bytecout = 0;} static long bytecount; }; long BufferedOutput::bytecount = 8;

定义静态成员函数的主要目的是访问静态的数据成员。

如在SavingAccount类中,当利率发生变化时,必须修改这个静态数据成员的值。为此可以设置一个静态的成员函数:

static void SetRate(double newRate) {rate = newRate;}

静态成员函数可定义为内嵌的,也可在类外定义。在类外定义时,不用static。

静态成员函数的访问:可以通过类作用域限定符或通过对象访问

类名::静态成员函数名();

4 static关键字的作用

1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值。

2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其他函数访问。

3)在模块内的static函数只可以被这一模块内的其他函数调用。这个函数的使用范围被限制在声明它的模块内。

4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝。

5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。

6) 对于静态(static)对象,当对象诞生时其构造式被执行;当程序将结束时(此对象因而将遭致毁灭)其析构式才被执行,但比全域对象的析构式早一步执行。

5 常见问题

1) 常量数据成员和静态常量数据成员有什么区别?如何初始化常量数据成员?如何初始化静态常量数据成员?

常量的数据成员指得是那些在对象生成时给定了初值,在整个对象的生命周期中,该数据成员的值是不能变的。常量数据成员的值必须在构造函数的初始化列表中进行初始化。静态的常量数据成员是整个类所有对象共享的一个常量。对整个类而言,不管定义了多少个对象,该成员永远只有一份拷贝。静态常量数据成员的值是在定义类时给定。

2) 静态成员函数不能操作非静态的数据成员,那么非静态的成员函数能否操作静态的数据成员?为什么?

因为静态成员函数没有隐含的this指针,所以不能够操作非静态的数据成员。静态的数据成员是所有对象共享的数据成员,在逻辑上是属于每一个对象的,所以非静态的成员函数可以操作静态的数据成员。

-End-

,