转自http://blog.csdn.net/shuigsls/archive/2008/07/13/2645918.aspx
一、函数
函数的引入可以减少 程序的目标代码,实现程序代码的共享。但是,函数调用也需要一些时间和空间方面的开销,因为调用函数实际上将程序执行流程转移到被调函数中,被调函数的程 序代码执行完后,再返回到调用的地方。这种调用操作要求调用前保护现场并记忆执行的地址,返回后恢复现场,并按原来保存的地址继续执行。对于较长的函数这 种开销可以忽略不计,但是对于一些函数体代码很短,但又被频繁地调用的函数,就不能忽视这种开销。引入内联函数和宏函数正是为了解决这个问题,提高程序的 运行效率。 在程序编译时,编译器将程序中出现的内联函数 ( 宏函数 ) 的调用表达式用 内联函数 ( 宏函数 ) 的函数体来进行替换。由于在编译时将函数体中的代码替代到程序中,因此会增加目标程序代码量,进而 增加空间开销,而在时间开销上不象函数调用时那么大,可见它是以目标代码的增加为代价来换取时间的节省。
在类静态数据成员不同于非静态的数据成员,一个类的静态数据成员仅创建和初始化一次,且在程序开始执行的时候创建,然后被该类的所有对象 共享;而非静态的数据成员则随着对象的创建而多次创建和初始化 ; static 成员是放在静态存储区的,它并不受访问控制符的限制,而其它的成员变量则是放在栈中的。
静态成员函数和非静态成员函数。这两者之间的一个重大区别是,静态成员函数不接受隐含的this自变量
类的静态成员(变量和方法)属于类本身,在类加载的时候就会分配内存,可以通过类名直接去访问;非静态成员(变量和方法)属于类的对象,所以只有在 类的对象产生(创建类的实例)时才会分配内存,然后通过类的对象(实例)去访问。
在一个类的静态成员中去访问其非静态成员之所以会出错是因为在类的非静态成员不存在的时候类的静态成员就已经存在了,访问一个内存中不存在的东西当 然会出错。
二、使用方面
1 : windows 的回调函数使用 静 态 函数 :
在类中, static 型的 成员函数,由于是类所拥有的,而不是具体对象所有的 ,这一点对于 windows 的 回调机制非常有用。因为对于回调函数而言, windows 不会借助任何对象去调用它,也就不会传递 this 指针,那么 对于一般成员函数作为回调函数的后果,就是堆栈中有一个随机的变量会成为 this 指针,这当然会引发程序的崩溃。而 static函数,由于是整个类的,屏蔽了 this 指针。因 此,如果成员函数作为回调函数,就应该用 static 去修饰它。
2 : 线程控制函数常 使用静态函数
静态函数 有特定的地址空间,这样可以避免在运行时 system 对内存 调整带来的问题。
3 : Windows 系统 API ,也常使用静态函数
调用方面,不用在调用前实例化。
三、实例代码
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <string.h>
class Directory
{
public:
// 静态公有的函数
Directory()
{
strcpy(strTemp,"/ 测试 ");
i=15;
}
static void setpath(char const *newpath);
static void setname( Directory *dir);
void getpath(char *oldpath);
char strTemp [50];
int i;
private:
// 静态字符串
static char path [];
};
// 静态数据成员的初始化
char Directory::path [199] = "/ 开始测试 ";
// 静态函数访问静态变量
void Directory::setpath(char const *newpath)
{
printf("path=%s/n",path);
strncpy(path, newpath, 199);
printf("path=%s/n",path);
}
// 静态函数访问非静态变量
void Directory::setname(Directory *dir)
{
dir->getpath("/ 静态函数访问非静态函数 ");
dir->strTemp;// 静态函数访问非静态变量
return;
}
// 非静态函数访问静态变量
void Directory::getpath(char *oldpath)
{
strncpy(Directory::path,oldpath, 199);
printf("Directory::path=%s/n",Directory::path);
}
// 使用实例
void main()
{
// 通过类名调用 setpath() 成员函数
//Directory::setpath("/ 通过类名调用静态成员函数 ");
// 通过对象调用 setpath() 成员函数
Directory dir;
dir.setpath("/ 静态函数访问静态变量 ");
dir.getpath("/ 非静态函数访问静态变量 ");
Directory *dira;
dir.setname(dira);
}