关于C++中全局函数跟静态成员函数的疑问

关于C++中全局函数和静态成员函数的疑问

// 关于C++中全局函数和静态成员函数的疑问

// 例如这样写:
class Kity  //类名没有意义
{
    static void fun();  //静态成员函数
};
void foo() { }  //全局函数
typedef void (*FUNPTR)();

int main()
{
    FUNPTR pfn1 = foo;  
    FUNPTR pfn2 = (FUNPTR)Kity::fun;  //总感觉这里出了点什么问题,但又不清不楚的。多希望有人能点到本质上来啊。
    // FUNPTR pfn2 = (FUNPTR)&Kity::fun;
    return 0;
}


------解决思路----------------------
《深度探索C++对象模型》
《C++反汇编与逆向分析技术揭秘》
------解决思路----------------------
函数指针,与类函数成员指针,两种不同类型的指针即使函数的参数、返回值一样;

这在c++primer中都有讲的,可以去看看。
------解决思路----------------------
很明白的告诉你,2种方法都没有问题,是正确的,不过都是地址罢了。
------解决思路----------------------
C++的真正意义上的成员函数在mangling的时候会将成员函数func()的名称编程类似这样的,func(void *),会在成员函数前面填充一个this指针。而static不会,就是直接按照C的方式进行mangling的。
C++里的static成员函数和成员变量你就不要把它当“类成员”去理解,直接当成是C风格的函数和变量就行了(全局),只不过使用时在编译的时候对public、private相关语法作了检测而已。



------解决思路----------------------
 static void fun();  //静态成员函数

如果你使用了static静态函数,函数fun()就可以在类的外面使用。

而不会出像栈那样的问题。
------解决思路----------------------
编译器差异会给你答案
------解决思路----------------------

C++ 允许函数名前面加个 &表示函数地址。 
你可能认为 有&的才是正确的,
但是不加& 的更原始,那是(兼容C)的方式。
其实 如果不需要修改 指针的内容,
可以用引用代替指针

------解决思路----------------------

class Kity  
{
public:
    static void fun()
{

}
};


改成这样

看下这篇文章
一般函数指针和类的成员函数指针
http://www.cnblogs.com/xianyunhe/archive/2011/11/26/2264709.html

------解决思路----------------------
类的static函数主要是影响了函数的名字而已,类型和全局那个是一样的,你写的Kity::fun本身就是代表函数的名字,没有什么特别的。
------解决思路----------------------

class Kity 
{
    static void fun(); //这个函数 有命名空间限制的,只可以在   Kity  类中被调用
};
void foo() { }  //全局函数 --- 这个是任何地方都可以调用的

------解决思路----------------------
6~7楼,你表达的很不准确,
对于静态函数,类外部,必须采用类名引用方式才能得到函数指针,或者调用函数
对于 非静态函数,成员函数指针,是成员指针的一种,
是一种特殊的指针,很多指针语法不适用成员指针。
成员指针,只有通过对象,才能引用,
因为编译器,不可能无中生有的创造一个,

程序员没有指定的对象,
来调用成员函数,或者读写成员变量的值。

编译器不知道,你用谁的成员指针,
做事情,所以必须指定对象。
才能使用成员指针
另外,对于C++你不可能,直接用C或者C++的方法,取得成员函数的地址。
你唯一可能的方式,
是通过调试或者,查看反汇编,以及查看目标代码,
等手段,来得到非静态函数的地址。

成员指针,丑陋,离奇,但是必须这么用
成员指针,包括成员函数指针,成员变量指针

例如


class C{
    public:
C(int x=0,int y=0,int z=0):a(x),b(y),c(z){};
int  a,b,c;

int fun_x(){cout <<"fun_x:a="<<a<<endl;return 0;};
int fun_y(){cout <<"fun_y:b="<<b<<endl;return 0;};
int fun_z(){cout <<"fun_z:c="<<c<<endl;return 0;};
static int fun_static(){cout <<"static " <<endl;return 0;};
};

///成员变量指针,是一种非独立数据,必须配合 对象,才能指向 对象的 成员变量.
///成员函数指针,同样是一种非独立数据,必须配合对象,成员函数指针,才有意义
///(通过对象,才能传递 隐含参数 this 这个指针,给函数)

int (&rfs)() = C::fun_static; //C++ 函数可以有引用,类静态函数也可以有引用
int (*pfs_0)() = &C::fun_static;
int (*pfs)() = C::fun_static; ///类静态函数,和类外定义的函数的差别,只是访问方式和,保护属性不同。作用域不同
                           ///所以指向它的指针,不需要成员(函数)指针,只需普通函数指针就可以了
int (C::*pfx)() =&C::fun_x; ///非静态成员函数,需要成员(函数)指针,普通函数指针不可以
int C::*pa =&C::a;     ///成员变量指针

int main()
{

    pfs();
    C c(1,2,3);
    C &r= c;
    C *p= &c;

   cout<<"obj:"; (c.*pfx)();
   cout<<"ref:"; (r.*pfx)();
   cout<<"ptr:"; (p->*pfx)();
    pfx =&C::fun_y;

   cout<<"obj:"; (c.*pfx)();
   cout<<"ref:"; (r.*pfx)();
   cout<<"ptr:"; (p->*pfx)();

    pfx =&C::fun_z;

   cout<<"obj:"; (c.*pfx)();
   cout<<"ref:"; (r.*pfx)();
   cout<<"ptr:"; (p->*pfx)();
    cout <<c.*pa<<endl;
    pa =&C::b;
    cout <<c.*pa<<endl;;
    pa =&C::c;
    cout <<c.*pa<<endl;;
    cout <<"staic member fun ref:";rfs();
    cout<<"staic member fun ptr unuse &:";pfs();
    cout<<"staic member fun ptr use &:";pfs_0();
    cout << "end!" << endl;

    return 0;
}

输出 
static
obj:fun_x:a=1
ref:fun_x:a=1
ptr:fun_x:a=1
obj:fun_y:b=2
ref:fun_y:b=2
ptr:fun_y:b=2
obj:fun_z:c=3
ref:fun_z:c=3
ptr:fun_z:c=3
1
2
3
staic member fun ref:static
staic member fun ptr unuse &:static
staic member fun ptr use &:static
end!