`
yidongkaifa
  • 浏览: 4052684 次
文章分类
社区版块
存档分类
最新评论

C++中使用非静态成员函数代替全局函数

 
阅读更多

我们需要一组功能函数,但又不想使用全局函数,以免污染命名空间,当然可以使用命令空间,也可以使用静态成员函数,但我们还有一种另类的方法,使用非静态成员函数。如下类:

class Util
{
private:
Util(){} // 我们只用于使用该类组织代码,但从不进行实例化
~Util(){};

public:
static float VERSION ;
void Func(int val)
{
cout<<"ObjA::Func( "<}
};

float Util::VERSION = 1.1F;

以后我们可能这样调用Util::Func()函数:

Util *pa =0;
pa->Func(__LINE__);

((Util*)0)->Func(__LINE__);

注意,既然pa是个空指针,则它不指向任何对象,Func函数也不能使用任何非静态成员变量。虽然从工程上讲,这样做的必要性让人疑,但这样做的确是可能的。如果把VERSION改为私有变量,好像这样做会更有意义一些,比如我们可以封装一些算法进去,其中可能用到一些常量,但这些常量又不想让用户看到,就可以将这些常量定义为私有的静态成员。无论如何,这种方式,都可以使用静态成员函数替代,现在还没有发现这种方式比静态成员函数比较优秀,如果硬是要提出来一种场景的话,那就是写一些让人难以琢磨的代码耍酷。其它的真的想不起来了。

再加一个静态成员函数:

class Util{ ...
static void Func2(int val)
{
cout<<"ObjA::Func( "< }
};

看看VC9调用这些函数的汇编代码

pa->Func(__LINE__);
004116A6 mov eax,dword ptr [`hard_exception_test'::`2'::__LINE__Var (41C010h)]
004116AB add eax,4
004116AE push eax
004116AF mov ecx,dword ptr [pa]
004116B2 call Util::Func (411203h)
((Util*)0)->Func(__LINE__);
004116B7 mov eax,dword ptr [`hard_exception_test'::`2'::__LINE__Var (41C010h)]
004116BC add eax,5
004116BF push eax
004116C0 xor ecx,ecx
004116C2 call Util::Func (411203h)
Util::Func2(__LINE__);
004116C7 mov eax,dword ptr [`hard_exception_test'::`2'::__LINE__Var (41C010h)]
004116CC add eax,6
004116CF push eax
004116D0 call Util::Func2 (4110E1h)

还是使用静态成员函数调用更直接一些,因为非静态函数函数在调用时要比静态成员函数调用多传递一个参数--this指针。当在成员函数中用到非静态成员变量时,就会通过this指针去访问该变量,但我们前两种调用时this指针指向的非法地址,那样的话操作系统会抛出非法访问的异常,导致程序意外终止。

实际上,查看汇编代码,很清楚,前两种调用是传递了this指针的,相当于传了一个指针参数,但我们没有使用该参数,所以不会出现异常。

无论从工程上,还是从效率上讲,这种调用方式都不及静态成员函数,但通过这种方式的分析可以更清楚C++类的封装机制的实现,实际上就是在C++的结构基础上增加了一个隐藏的this指针,编译器为成员函数自动增加了一个参数,交自动将this指针作为实参传递给函数。

程序在VC9及g++ (for cygwin)都通过了,没有问题。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics