成员函数的指针解决思路
成员函数的指针
class Foo
{
private :
int t_ ;
public :
Foo ( int t ) : t_ ( t )
{
}
virtual bool f1 ( int i )
{
cout < < "f1 " < <endl;
return i > t_ ;
}
virtual bool f2(int i)
{
cout < < "f2 " < <endl;
return i> t_;
}
} ;
int main ()
{
bool (Foo::*pmfn)(int) ;
pmfn = &Foo::f1 ;
Foo foo ( 10 ) ;
if ( (foo.*pmfn)( 11 ))//
std::cout < < "pmfn ( 11 ) true\n " ;
return 0 ;
}
你说(foo.*pmfn+1)( 11 )做了什么?,未定义么?我还以为他会指向f2呢
------解决方案--------------------
(foo.*pmfn+1)( 11 )能编译通过?
------解决方案--------------------
什么编译器?
------解决方案--------------------
编译应当可以通过吧,试一把
------解决方案--------------------
编译器通过不了
vs.net 2003
------解决方案--------------------
vc6.0果然可以通过
155: if ( (foo.*pmfn + 1)( 11 ))//
156: std::cout < < "pmfn ( 11 ) true\n " ;
004013D9 push offset string "pmfn ( 11 ) true\n " (0043201c)
004013DE push offset std::cout (00439528)
004013E3 call @ILT+170(std::operator < <) (004010af)
004013E8 add esp,8
想不到最后生成的汇编代码居然是这样子的.debug的版本,没有任何优化选项...
------解决方案--------------------
输出“pmfn ( 11 ) true”并不表示 (foo.*pmfn+1)( 11 ) 运算成功了(或部分成功)。事实上,它根本没有运算。如果你这样写:
if (!(foo.*pmfn+1)( 11 ))
std::cout < < "pmfn ( 11 ) true\n " ;
仍然输出“pmfn ( 11 ) true”。
我认为,对于(foo.*pmfn+1)( 11 ) 这样错误的式子,编译器根本没有不生成任何代码。但是居然也不抱错,真有意思(我使用了VS2005).
------解决方案--------------------
l楼上的朋友错了吧.
bool (Foo::*pmfn)(int) ; //指向类Foo的成员函数的指针函数(只能指向只含一个参数的成员函数)
pmfn = &Foo::f1 ; //指针函数指向了类Foo::f1的地址
Foo foo( 10 ); //构造了一个Foo对象
if ((foo.*pmfn)( 11 )) //调用指针函数
std::cout < < "pmfn ( 11 ) true\n " ;
在这里有必要指出,C++中对成员函数的管理和JAVA有点象,他们都只在内存中存在一分拷贝,也就是说函数在内存中和一般的静态变量一样属于类,而不属于对象(他们是纯代码,用户可以访问不可以修改).所以可以用函数指针指向这唯一的地址,并调用它.
不知这样回答,各位可能够明白啊?
谢谢了!
class Foo
{
private :
int t_ ;
public :
Foo ( int t ) : t_ ( t )
{
}
virtual bool f1 ( int i )
{
cout < < "f1 " < <endl;
return i > t_ ;
}
virtual bool f2(int i)
{
cout < < "f2 " < <endl;
return i> t_;
}
} ;
int main ()
{
bool (Foo::*pmfn)(int) ;
pmfn = &Foo::f1 ;
Foo foo ( 10 ) ;
if ( (foo.*pmfn)( 11 ))//
std::cout < < "pmfn ( 11 ) true\n " ;
return 0 ;
}
你说(foo.*pmfn+1)( 11 )做了什么?,未定义么?我还以为他会指向f2呢
------解决方案--------------------
(foo.*pmfn+1)( 11 )能编译通过?
------解决方案--------------------
什么编译器?
------解决方案--------------------
编译应当可以通过吧,试一把
------解决方案--------------------
编译器通过不了
vs.net 2003
------解决方案--------------------
vc6.0果然可以通过
155: if ( (foo.*pmfn + 1)( 11 ))//
156: std::cout < < "pmfn ( 11 ) true\n " ;
004013D9 push offset string "pmfn ( 11 ) true\n " (0043201c)
004013DE push offset std::cout (00439528)
004013E3 call @ILT+170(std::operator < <) (004010af)
004013E8 add esp,8
想不到最后生成的汇编代码居然是这样子的.debug的版本,没有任何优化选项...
------解决方案--------------------
输出“pmfn ( 11 ) true”并不表示 (foo.*pmfn+1)( 11 ) 运算成功了(或部分成功)。事实上,它根本没有运算。如果你这样写:
if (!(foo.*pmfn+1)( 11 ))
std::cout < < "pmfn ( 11 ) true\n " ;
仍然输出“pmfn ( 11 ) true”。
我认为,对于(foo.*pmfn+1)( 11 ) 这样错误的式子,编译器根本没有不生成任何代码。但是居然也不抱错,真有意思(我使用了VS2005).
------解决方案--------------------
l楼上的朋友错了吧.
bool (Foo::*pmfn)(int) ; //指向类Foo的成员函数的指针函数(只能指向只含一个参数的成员函数)
pmfn = &Foo::f1 ; //指针函数指向了类Foo::f1的地址
Foo foo( 10 ); //构造了一个Foo对象
if ((foo.*pmfn)( 11 )) //调用指针函数
std::cout < < "pmfn ( 11 ) true\n " ;
在这里有必要指出,C++中对成员函数的管理和JAVA有点象,他们都只在内存中存在一分拷贝,也就是说函数在内存中和一般的静态变量一样属于类,而不属于对象(他们是纯代码,用户可以访问不可以修改).所以可以用函数指针指向这唯一的地址,并调用它.
不知这样回答,各位可能够明白啊?
谢谢了!