c++ 静态对象 操作(static)

静态对象是一种从构造开始到程序结束都存在的一种对象.它是独立于栈与堆的。

静态存储

变量定义在函数外或是用static关键字修饰的变量存放在静态存储区.放在静态存储区的数据在整个程序运行其间持续有效。

 

那些变量可以依据linkage分为以下三类:

l  external linkage

l  internal linkage

l  no linkage

 

既然在程序的整个生命周期都存在,这样的好处就是非常容易进行内存管理。

 

下面例子就是静态变量的不同作用域的示例.

int a= 1;
static int b = 2;
int main() {}
void f() {
	static int c = 3;
	int d = 4;
}

所有的静态变量都持续到程序结束.变量d是本地作用域,不能在函数f()以外使用。但变量c存在内存中即使f()函数没有被执行。通过声明c是静态的,我就可以声明其一次并只能声明一次。

a和b两个变量能从声明位置,到整个文件结束都能被访问到。但a能在其它文件中使用因为其默认为 external linkage。

 

所有静态变量有如下初始化特性:

l  为初始化的变量设置为0

l  初始化静态变量只能是固定表达式.

int x;               // x set to 0

int y = 50;          // 50 is literal constant

int z = sizeof(int); // sizeof ok

int zz = 10 * x;     // not allowed, x is not constant

int main()

{...}

 

Const 与 Extern

const 在c++中对默认存储类做了些扭转.一个全局变量默认是external linkage,一个const的全局变量默认是internal linkage.也就是说c++处理全局const变量的定义取决于其是否有static。

const int a = 10;

int main() { ....

所以,const int a = 10 变成 static const int a = 10.然而,如果全局const有 externallinkage,这个const全局变量定义就会有出错,因为我们只能在一个文件中定义全局变量。也就是说,只有一个文件能提前声明,其它的文件必需通过extern关键字提供相关声明的引用。必需注意只有不用extern声明的地方能初始化值。

 

然而,如果我们想使constant变量有external linkage,我们可以用extern关键字声明来代替默认的inernal linkage:

Extern const  int a = 20;

 

这里,我们应该使用extern关键字在所用到此constant变量的文件中进行声明。这就是一般external变量与constant变量的不同。对于一般变量来说我们不需要在定义变量时使用extern关键字,但我们在其它使用此变量的文件中使用extern来引用此变量。

 

静态存储与动态审请

动态审请内存是通过new与delete操作符,不是通过作用域和外部引用,可以动态审请能在一个函数中审请或一个函数中释放。

 

然而这种存储方式不能应用于动态内存,而是用一个自动静态指针变量来跟综动态内存。

 

我们来看一下下面的示例代码:

int *ptr = new int[10];

 

这里有40个字节的内存被new审请会一直存在,直到delete来释放.但ptr指针持续存在直到声明此变量的函数结束。

 

如果我们想在其它的函数中使用这40个字节的内存,我们需要传或返回这个指针地址到其使用的函数。

 

也就是说,如果我们使用external linkage来声明ptr,这个ptr指通过已下方式可用:

extern int *ptr;

 

静态类成员

静态成员是做为这个类的成员而不是这个类的每一个实例存在。所以关键字this不能在静态成员中使用。静态函数只能使用静态的数据成员。整个类中静态成员只有一个实例,通常在实现源文件中被初始化。

class_name::static_member_name = value;

 

下面是实例代码 Car.h文件:

class Car

{

private:

         staticint id;

public:

        Car();

...

};

实现文件,Car.cpp:

#include <iostream>

 

int Car::id = 100;

...

Car::Car() {}

....

上面代码初始化静态变量 id 的值为100.再次提未我们不能在声时静态变量时进行初始化.因为声明只是告诉编译器多少内存被审请,而不进行审请操作.我们只有在建立对象时才进行内存的审请及初始化。

 

在这个静态数据成员的例子中,我们单独的初始化静态数据成员,在类外进行声明。因为静态成员的存储方式与是与普通的类对象分开的。

 

但是在在类的声明里面可以初始化const或 enumeration类型的静态成员:

#include <iostream>

 

class Car

{

         enumColor {silver = 0, maroon, red }; 

         intyear;

         intmileage = 34289;                   //error: not-static data members

                                                // onlystatic const integral data members

                                                // canbe initialized within a class

 

         staticint vin = 12345678;             // error:non-constant data member

                                                // only static constintegral data members

                                                // canbe initialized within a class

 

         staticconst string model = "Sonata"; // error: not-integral type

                                                // cannothave in-class initializer

 

         staticconst int engine = 6;           //allowed: static const integral type

};

 

int Car::year = 2012;                          // error: non-staticdata members

                                              // cannot be defined out-of-class

 

int main()

{

         return0;

}

 

静态函数的特性:

l  一个静态成员函数只能访问静态数据,静态函数及类外的数据和函数。所以我们必需注意不要向非静态成员一样使用静态成员函数,非静态函数能访问所有的静态数据成员。

l  我们必需首先明白静态数据成员的概念.我们可以在一个类中声明一个静态数据成员,而不管此类的的访问方式是public还是private的。如果一个数据成员声明为静态的,这个数据成员只能被创建及初始化一次.非静态数据可以被创建及初始化N次。静态数据成员的基本概念就是所有类对象共享一个静态变量。

l  一个非静态函数只能在类对象初化时才能被调用。而静态数据成员可以在类没有初始化时就可以被调用。

l  一个非静态函数可以被声明为virtual但静态数据成员不能声明为virtual.


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值