关于C++中全局函数跟静态成员函数的疑问
关于C++中全局函数和静态成员函数的疑问
------解决思路----------------------
《深度探索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)的方式。
其实 如果不需要修改 指针的内容,
可以用引用代替指针
------解决思路----------------------
改成这样
看下这篇文章
一般函数指针和类的成员函数指针
http://www.cnblogs.com/xianyunhe/archive/2011/11/26/2264709.html
------解决思路----------------------
类的static函数主要是影响了函数的名字而已,类型和全局那个是一样的,你写的Kity::fun本身就是代表函数的名字,没有什么特别的。
------解决思路----------------------
------解决思路----------------------
// 关于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!