c++,在类中使用函数指针时碰上错误:表达式必须具有 (pointer to int cast-to-) 函数类型

明显调用的表达式前的括号必须具有(指针)函数类型 编译器错误 C2064 - superCPP
来源:互联网
编辑:刘梓楠
有网友碰到过这样的问题:明显调用的表达式前的括号必须具有(指针)函数类型 编译器错误 C2064 - superCPP,问题详细内容为:挺不错的博文:明显调用的表达式前的括号必须具有(指针)函数类型 编译器错误 C2064 - superCPP,我搜你通过互联网收集了相关的一些解决方案,希望对有过相同或者相似问题的网友提供帮助,具体如下:
看到&明显调用的表达式前的括号必须具有(指针)函数类型&这句时我才发现我的语文水平有多烂,怎么看都看不懂,折腾了半天才知道是哪里出了问题。
举个简单的例子
class CTest
void (CTest::*m_pFun)();
void CallFun()
(this-&*m_pFun)(); //OK,对象指针和函数名一定要用括号括起来,函数名前面要加上*号
this-&*m_pFun(); //error
(this-&m_pFun)(); //error
//本文链接/vcpp123/p/5902839.html
详细说明请参阅MSDN,链接:/query/dev14.query?appId=Dev14IDEF1&l=ZH-CN&k=k(C2064)&rd=true
编译器错误 C2064
term does not evaluate to a function taking N arguments
A call is made to a function through an expression.The expression does not evaluate to a pointer to a function that takes the specified number of arguments.
In this example, the code attempts to call non-functions as functions.The following sample generates C2064:
// C2064.cpp
void func() {
// C2064, i is not a function
// C2064, p doesn't point to a function
You must call pointers to non-static member functions from the context of an object instance.The following sample generates C2064, and shows how to fix it:
// C2064b.cpp
struct C {
void func1() {}
void func2() {}
typedef void (C::*pFunc)();
int main() {
pFunc funcArray[2] = { &C::func1, &C::func2 };
(funcArray[0])();
(c.*funcArray[0])(); // OK - function called in instance context
Within a class, member function pointers must also indicate the calling object context.The following sample generates C2064 and shows how to fix it:
// C2064d.cpp
// Compile by using: cl /c /W4 C2064d.cpp
struct C {
typedef void (C::*pFunc)();
pFunc funcArray[2];
void func1() {}
void func2() {}
funcArray[0] = &C::func1;
funcArray[1] = &C::func2;
void func3() {
(funcArray[0])();
(this-&*funcArray[0])(); // OK - called in this instance context
posted @ 请注意,本站信息均收集自互联网,相关信息仅供参考,医疗等重要信息请以正规途径为最终意见,本站不承担任何责任!
您可能还关注您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
C+++习题及解答(第3版).doc111页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
文档加载中...广告还剩秒
需要金币:100 &&
你可能关注的文档:
··········
··········
9.在100到200中找出同时满足用3除余2,用5除余3和用7除余2的所有整数。
200; i++ if i % 3
2 10.求100到999中的水仙花数。所谓水仙花数是指一个三位数,它的每位数字的立方之和等于该数。例如,因为153 1+5+3,所以153为水仙花数。
int main int i,a,b,c;
999; i++ a
i/100; b i-a*100
i - a*100 - b*10; if
a*a*a + b*b*b + c*c* 11.求1000之内的所有完数。所谓完数是指一个数恰好等于它的所有因子之和。例如,因为6 1+2+3,所以6为完数。
int main int i,j,s; for
1000; i++ s
j 1; j++ if
s 12.编一程序显示由符号组成的三角形图案。例如,程序运行后,
屏幕显示: How many lines ?
用户输入: 5
屏幕显示: What character ?
用户输入: *
则输出如下图案。
* * * * * * *
* * * * * * * * *
int main int i,j,k,n;
"How many lines ?\n";
"What character ?\n";
i 1; i++ for
2*i-1; j++ 13.已知XYZ+YZZ 532,其中X,Y和Z为数字,编一程序求出X,Y和Z的值。
int main int x,y,z,i;
9; x++ for
9; y++ for
100*x + 10*y + z + 100*y + 10*z + if
"z " 习题3及其解答
1.以下正确的函数原型为
正在加载中,请稍后...您所在的位置: &
浅谈C++指针直接调用类成员函数
浅谈C++指针直接调用类成员函数
本文分析了C++编程中用指针调用“类” 成员函数时出现的问题、原因及后果,讨论了一般函数指针和“类”成员函数指针的不同。得出结论:任何指向“类”的成员函数指针,由于携带额外的所属对象信息,与一般的函数有根本的不同,不能直接用来进行函数调用。此外,本文给出了几种间接调用类的成员函数的方法。
在编程工作中常会遇到在一个&类&中通过函数指针调用成员函数的要求,如,当在一个类中使用了C++标准库中的排序函数qsort时,因qsort参数需要一个&比较函数&指针,如果这个&类&使用某个成员函数作&比较函数&,就需要将这个成员函数的指针传给qsort供其调用。本文所讨论的用指针调用 &类&的成员函数包括以下三种情况:
(1).将 &类&的成员函数指针赋予同类型非成员函数指针,如:
#include&&stdlib.h& &typedef&void&(*Function1)(&);&&Function1&f1; &class&Test1 &{ & public:& &&void&Memberfun1(&){&printf(&%s&\n&,&Calling&Test3::Memberfun2&OK&);};&&void&Memberfun2() &{ & f1=reinterpret_cast&Function1&(Memberfun1);& f1(); &} &&}; &int&main() &{ & Test1&t1; & t1.Memberfun2(); & return&0; &}&
(2) 在一个&类&内,有标准库函数,如qsort, 或其他全局函数,用函数指针调用类的成员函数。如:
#include&&stdlib.h& &class&Test2 &{ &private:& &int&data[2];& &&public: &&int&__cdecl&Compare(const&void*&elem1,&const&void*&elem2)&&{& &printf(&%s&\n&,&Calling&Test2::Memberfun&OK&); &return&*((int*)elem1)-&*((int*)elem2)&;& &} &void&Memberfun()& &{& &data[0]=2;&data[1]=5; &qsort(&data,&2,&sizeof(int),&Compare);&&&} &&}; &int&main(&) &{ &Test2&t2; &t2.Memberfun();&&return&0; &}&&
(3)同一个&类&内,一个成员函数调用另一个成员函数, 如:
#include&&stdlib.h& &class&Test3 &{ &public: &&void&Memberfun1(&void&(*&f2)(&)&)&{&f2(&)&;}&&void&Memberfun2(&)&{&printf(&%s&\n&,&Calling&Test3::Memberfun2&OK&);}&&void&Memberfun3(&)&{&Memberfun1(&Memberfun2);}&&&}; &int&main(&) &{ &Test3&t3; &t3.Memberfun3();&&return&0; &}&
以上三种情况的代码语法上没有显著的错误,在一些较早的编译环境中,如,VC++ 4.0, 通常可以编译通过,或至多给出问题提醒(Warning)。后来的编译工具,如,VC++6.0和其他一些常用的C++编译软件,不能通过以上代码的编译, 并指出错误如下(以第三种情况用VC++ 6.0编译为例):
error C2664: 'Memberfun1' : cannot convert parameter 1 from 'void (void)' to 'void (__cdecl *)(void)'
None of the functions with this name in scope match the target type
即:Memberfun1参数中所调用的函数类型不对。
按照以上提示,仅通过改变函数的类型无法消除错误,但是,如果单将这几个函数从类的定义中拿出来,不作任何改变就可以消除错误通过编译, 仍以第三种情况为例,以下代码可通过编译:
#include&&stdlib.h& &void&Memberfun1(&void&(*&f2)(&)&)&{&f2(&)&;}&&void&Memberfun2(&)&{&printf(&%s&\n&,&Calling&Test3::Memberfun2&OK&);}&&void&Memberfun3(&)&{&Memberfun1(&Memberfun2);} &int&main(&) &{ &Memberfun3&(); &return&0; &}&
第1、 2种情况和第3种情况完全相同。
由此可以的得出结论,以上三种情况编译不能通过的原因表面上并不在于函数类型调用不对,而是与 &类&有关。没通过编译的情况是用函数指针调用了 &类&的成员函数,通过编译的是用函数指针调用了非成员函数,而函数的类型完全相同。那么, &类&的成员函数指针和非成员函数指针有什么不同吗?
在下面的程序中,用sizeof()函数可以查看各种&类&的成员函数指针和非成员函数指针的长度(size)并输出到屏幕上。
#include&&stdafx.h& &#include&&iostream& &#include&&typeinfo.h& &class&T&&class&Test2&&{ &}; &class&Test3&&{ & public: &&void&(*&memberfun)(); &void&Memberfun1(&void&(*&f2)(&)&)&{&f2(&)&;}&&void&Memberfun2(&);&&}; &class&Test4:&virtual&Test3&,Test2&&{ & public: &void&Memberfun1(&void&(*&f2)(&)&)&{&f2(&)&;}& &}; &class&Test5:&Test3,Test2&&{ & public: &void&Memberfun1(&void&(*&f2)(&)&)&{&f2(&)&;}& &}; &&int&main() &{ & std::cout&&&&一般函数指针长度=&&&&&sizeof(void(*)())&&&&'\n'; & std::cout&&&&-类的成员函数指针长度-&&&'\n'&&'\n'; & std::cout&&&&Test3类成员函数指针长度=&&&&sizeof(void(Test3::*)())&&'\n'&&'\n'; & std::cout&&&&Test5类成员函数指针长度=&&&sizeof(void&(Test5::&*)())&&'\n'; & std::cout&&&&Test4类成员函数指针长度=&&&sizeof(void&(Test4::&*)())&&'\n'; & std::cout&&&&Test类成员函数指针长度=&&&sizeof(void(Test::*)())&&&'\n'; & return&0; &}&
输出结果为(VC++6.0编译,运行于Win98操作系统,其他操作系统可能有所不同):
一般非成员函数指针长度= 4
-类的成员函数指针长度-
Test3类成员函数指针长度=4
Test5类成员函数指针长度=8
Test4类成员函数指针长度=12
Test类成员函数指针长度=16
以上结果表明,在32位Win98操作系统中,一般函数指针的长度为4个字节(32位),而类的成员函数指针的长度随类的定义与否、类的继承种类和关系而变,从无继承关系类(Test3)的4字节(32位)到有虚继承关系类(Virtual Inheritance)(Test4)的12字节(96位),仅有说明(declaration)没有定义的类(Test)因为与其有关的一些信息不明确成员函数指针最长为16字节(128位)。显然, 与一般函数指针不同,指向&类&的成员函数的指针不仅包含成员函数地址的信息,而且包含与类的属性有关的信息,因此,一般函数指针和类的成员函数指针是根本不同的两种类型,当然,也就不能用一般函数指针直接调用类的成员函数,这就是为什么本文开始提到的三种情况编译出错的原因。尽管使用较早版本的编译软件编译仍然可以通过,但这会给程序留下严重的隐患。
至于为什么同样是指向类的成员函数的指针,其长度竟然不同,从32位到128位,差别很大,由于没有看到微软官方的资料只能推测VC++6.0在编译时对类的成员函数指针进行了优化,以尽量缩短指针长度,毕竟使用128位或96位指针在32位操作系统上对程序性能会有影响。但是,无论如何优化,类的成员函数指针包含一定量的对象(Objects)信息是确定的。其他的操作系统和编译软件是否进行了类似的处理,读者可以用以上程序自己验证。
那么,当需要时,如何用指针调用类的成员函数?可以考虑以下方法:
(1) 将需要调用的成员函数设为static 类型,如:在前述例子2中,将class Test2 成员函数Compare 定义前加上static 如下(黑体为改变之处):
class&Test2 &{ &&int&static&__cdecl&Compare(const&void*&elem1,&const&void*&elem2)&&&}&
改变后的代码编译顺利通过。原因是,static 类型的成员函数与类是分开的,其函数指针也不包含对象信息,与一般函数指针一致。这种方法虽然简便,但有两个缺点:1、被调用的函数成员定义内不能出现任何类的成员(包括变量和函数);2、由于使用了static 成员,类在被继承时受到了限制。
(2) 使用一个函数参数含有对象信息的static 类型的成员函数为中转间接地调用其他成员函数,以例3为例,将类Test3作如下修改(黑体字为修改之处),main()函数不变,则可顺利通过编译:
class&Test3 &{ & public: &&void&static&__cdecl&Helper(Test3*&test3) &{ & test3-&Memberfun2(); &} &void&Memberfun1(&void&(*&f2)(Test3*))&{&f2(this)&;}&&void&Memberfun2(&)&{printf(&%s&\n&,&Calling&Test3::Memberfun2&OK&);&}&&void&Memberfun3(&)&{&Memberfun1(&Helper);}& &&};&
这种间接方式对成员函数没有任何限制,克服了第一种方法成员函数不能使用任何类的成员的缺点,但由于有static 成员,类的继承仍受到制约。
(3)使用一个全程函数(global function)为中转间接调用类的成员函数,仍以例3为例,将代码作如下修改(VC++6.0编译通过):
class&Test3; &void&__cdecl&Helper(Test3*&test3); &class&Test3 &{ & public: &&void&Memberfun1(&void&(*&f2)(Test3*))&{&f2(this)&;}&&void&Memberfun2(&)&{printf(&%s&\n&,&Calling&Test3::Memberfun2&OK&);&}&&void&Memberfun3(&)&{&Memberfun1(&Helper);}& &&}; &&void&__cdecl&Helper(Test3*&test3) &{ & test3-&Memberfun2(); &};&
这个方法对成员函数没有任何要求,但是需要较多的代码。
除上述三种方法外还有其他方法,如, 可以在汇编层面上修改代码解决上述问题等,不属于本文范围。
结论:函数指针不能直接调用类的成员函数,需采取间接的方法,原因是成员函数指针与一般函数指针有根本的不同,成员函数指针除包含地址信息外,同时携带其所属对象信息。本文提供三种办法用于间接调用成员函数。这三种办法各有优缺点,适用于不同的场合。
希望通过以上内容的介绍,能够给大家带来帮助。【编辑推荐】【责任编辑: TEL:(010)】
关于的更多文章
Linux之父对C++进行了炮轰,说它是糟糕程序员的垃圾语言,可谓是
国内网盘的关停让用户操碎了心 下一个风口在哪
在过去的近十年的时间里,面向对象编程大行其道。以至
很久很久以前,冬天爱上了夏天,可是他们始终不能相见
流火过,金秋来,在学校开学之前的最后一周,终于凉快
本书是作者根据十年网站营销经验,特别是搜索引擎优化(SEO)实现营销方面的技术和实践总结。本书帮助读者建立搜索营销的概念,
51CTO旗下网站明显调用的表达式前的括号必须具有(指针)函数类型 编译器错误 C2064
来源:博客园
看到“明显调用的表达式前的括号必须具有(指针)函数类型”这句时我才发现我的语文水平有多烂,怎么看都看不懂,折腾了半天才知道是哪里出了问题。 举个简单的例子 class CTest{ void (CTest::*m_pFun)();
void CallFun() {
(this->*m_pFun)(); //OK,对象指针和函数名一定要用括号括起来,函数名前面要加上*号
this->*m_pFun(); //error
(this->m_pFun)(); //error }
//本文链接/vcpp123/p/5902839.html}; 详细说明请参阅MSDN,链接: /query/dev14.query?appId=Dev14IDEF1&l=ZH-CN&k=k(C2064)&rd=true 编译器错误 C2064 term does not evaluate to a function taking N arguments A call is made to a function through an expression. The expression does not evaluate to a pointer to a function that takes the specified number of arguments. In this example, the code attempts to call non-functions as functions. The following sample generates C2064: // C2064.cppint i,char*void func() { j = i();
// C2064, i is not a function p();
// C2064, p doesn't point to a function} You must call pointers to non-static member functions from the context of an object instance. The following sample generates C2064, and shows how to fix it: // C2064b.cppstruct C { void func1() {} void func2() {}};typedef void (C::*pFunc)();int main() { C pFunc funcArray[2] = { &C::func1, &C::func2 }; (funcArray[0])();
(c.*funcArray[0])(); // OK - function called in instance context} Within a class, member function pointers must also indicate the calling object context. The following sample generates C2064 and shows how to fix it: // C2064d.cpp// Compile by using: cl /c /W4 C2064d.cppstruct C { typedef void (C::*pFunc)(); pFunc funcArray[2]; void func1() {} void func2() {} C() {
funcArray[0] = &C::func1;
funcArray[1] = &C::func2; } void func3() {
(funcArray[0])();
(this->*funcArray[0])(); // OK - called in this instance context }};
免责声明:本站部分内容、图片、文字、视频等来自于互联网,仅供大家学习与交流。相关内容如涉嫌侵犯您的知识产权或其他合法权益,请向本站发送有效通知,我们会及时处理。反馈邮箱&&&&。
学生服务号
在线咨询,奖学金返现,名师点评,等你来互动

我要回帖

更多关于 setfilepointer函数 的文章

 

随机推荐