c/c++中static、auto、extern

来源:互联网 发布:skype for mac 编辑:程序博客网 时间:2024/06/05 16:46

面向过程设计中的static

1、静态全局变量

在全局变量前加static,该全局变量为静态全局变量,只能在当前文件中(就是当前cpp文件中)使用,别的cpp文件如果用extern来声明存在这样一个变量,则在链接时会提示无法解析外部符号。


例:

//a.cpp

static int a;

//b.cpp

exterin int a;

int main()

{

a = 1;

}

报错,无法解析外部符号a。


2、静态局部变量

在局部变量前,加关键字static,改变量就为静态局部变量,同样的,全局数据区中的内存也只分配一次;其作用域为局部作用域,在函数返回后或语句块结束时,作用域也结束。



已初始化的的全局变量和局部静态变量存放在.data段,未初始化的全局变量和局部静态变量一般存放在.bss段里,前者在生产可执行文件时就分配好内存了,后者在加载时才分配这段话说的对不对?

3、静态函数


在函数返回类型(定义或者声明中任意一个)前加static,函数即定义为静态函数,该函数不可以被其他文件引用。

例:

//a.cpp

#include"iostream"
using namespace std;
static void funA();
void funA()


{
cout<<"FUNA"<<endl;
}

//b.cpp

void funA();
int main()
{
funA();


}

程序会报错“无法解析外部函数funA()”。在b.cpp文件中声明funA函数时没有加extern,这是因为有些编译器(不确定是不是全部?)会自动将所有函数默认为extern类型(就如变量会默认为auto类型)。上述程序只要将static去掉即可正常运行。在函数编译完成,生成a.obj,b.obj后,链接器将他们链接成为可执行文件。平时编写cpp文件时,习惯将函数声明放在头文件中,然后其他cpp文件需要用到这里的函数时,只要包含头文件即可,这其实就是省去了在其他cpp文件中声明一遍外部函数的过程(include自动把函数的声明都包含进去了),事实上不用include头文件,自己非要写一遍声明,外部函数也是可以用的,就如上例。


面向对象的static关键字


1、静态成员变量

在类的声明内,变量的声明前加上static,该变量就为静态成员变量,其特点是,相对于非静态成员变量在每个对象中都有自己的拷贝,静态成员变量在程序中只有一份,被该类所有的对象所共享,故它必须在类外声明,以在全局变量区分配内存并初始化(也可以这样理解,如果它是在对象实例定义的时候被分配内存,岂不是每一个对象都有一个该静态变量的拷贝了?)其初始化格式为  数据类型 类名::静态成员变量名 = XXX


例:

#include <iostream>
using namespace std;
class Myclass
{
public:
         Myclass(int a,int b,int c);
         void GetSum();
private:
         int a,b,c;
         static int Sum;//声明静态数据成员
};
int Myclass::Sum=0;//定义并初始化静态数据成员,必须在类的声明外做,声明内是不能分配内存的
 
Myclass::Myclass(int a,int b,int c)
{
         this->a=a;
         this->b=b;
         this->c=c;
         Sum+=a+b+c;
}
 
void Myclass::GetSum()
{
         cout<<"Sum="<<Sum<<endl;
}
 
void main()
{
         Myclass M(1,2,3);
         M.GetSum();
         Myclass N(4,5,6);
         N.GetSum();
 
}

输出结果 Sum=6 Sum = 21


同时由于静态成员变量不属于某一个对象,因此在没有对象实例时,如果静态成员变量是public成员就可以对他进行操作。

有两种访问形式

   类名::静态成员变量名 

   类的对象名.静态成员变量名


2、静态成员函数

静态成员函数只能访问同一类的静态成员变量,而不可以调用类的非静态成员,这是因为静态成员函数没有this指针。

需要注意的是,静态成员函数只可以声明在类的声明中(static关键字只能出现在类的声明中)

例如 

class A{

void foo()

}

static A::foo()//报错

{

}

同时,静态成员函数也只能调用静态成员函数,而不能调用非静态成员函数。

另外,静态成员函数的地址可以用普通函数指针存储,而普通成员函数的地址需要用类成员函数指针来储存。举例如下: 
class base{ 
static int func1(); 
int func2(); 
}; 

int (*pf1)()=&base::func1;//普通的函数指针 
int (base::*pf2)()=&base::func2;//成员函数指针 

原创粉丝点击