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>static修饰的变量
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.
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论