此指向非静态成员函数代码的指针不起作用的原因是什么?



这就是我要做的:

class A {
public:
void(*fPtr)();
};
class B {
int ib = 2;
public:
void memf() {
printf("ib = %in", ib);
}
};
class C {
int ic = 6;
public:
void memf() {
printf("ic = %in", ic);
}
};
int main()
{
B b;
C c;
A a1;
A a2;
a1.fPtr = b.memf;
a2.fPtr = c.memf;
}

基本上是一个具有函数指针的类。此函数指针可以指向普通函数或成员函数。

然而,我在Visual Studio中遇到的错误:

Error   C2440   '=': cannot convert from 'void (__thiscall B::* )(void)' to 'void (__cdecl *)(void)'
Error   C2440   '=': cannot convert from 'void (__thiscall C::* )(void)' to 'void (__cdecl *)(void)'    
Error   C3867   'B::memf': non-standard syntax; use '&' to create a pointer to member
Error   C3867   'C::memf': non-standard syntax; use '&' to create a pointer to member

我知道这看起来可能是重复的,也许是。我没有使用推荐的解决方案,比如使用<functional>

有人能告诉我如何做对吗?这样我就能明白我做错了什么?我也想知道为什么标准方式不起作用。

换句话说:更正我的代码;(我真的很感激。

要了解这会导致问题的原因,最简单的方法是问——如果您确实调用了函数指针指向的函数,那么接收器对象会是什么?例如,假设您指向B::memf,然后通过fptr调用它。该函数需要相对于B对象进行操作,以便它可以读取该B对象的ib字段的值。但我们没有办法弄清楚要使用什么B对象——糟糕的时候!

(非静态(成员函数与自由函数不同的原因是,它们有一个表示接收器对象的隐式参数,因此在调用该函数时,需要有某种方法来指定该对象是什么

这个网站上的其他答案应该能够提供一些关于解决这个问题的可能策略的信息,但希望这能从一开始就揭示这个问题是什么。

这里有一个可能的问题解决方案:不过我做了一些小的更改。

  • 1st-我将Class A更改为Class Template
  • 2nd-我添加了一个指向类型<T>的指针作为类成员
  • 3rd-我向A<T>添加了一个operator()()来调用函数调用
  • 4th-为了保持一致,我更改了函数指针的名称和其他类的函数的名称
  • 5th-我使用的不是printf(),而是std::cout

以下是修改后的代码:阅读注释以了解其工作原理

template<class T>
class A {
private:
// Need to save a pointer to the class to have a realitive object.
T* ptrT{ nullptr };
public:
// Assigns the pointer of the object to this's class's pointer member.
// Must pass by reference otherwise you will have undefined behavior.
explicit A( T& t ) : ptrT( &t ) {}
// Notice the Template Arguments class resolution operator...
void(T::*func)();
// The added operator()() to invoke the function call.
// This could of been any arbitrary member function; 
// I just chose to use the operator() for demonstration.
void operator()() {
(ptrT->*func)();
}
};
// In class's A & B the only changes here are 
// the names of the function and replacing printf() with cout
class B {
int ib{ 2 };
public:
void func() {
std::cout << ib << 'n';
}
};
class C {
int ic{ 6 };
public:
void func() {
std::cout << ic << 'n';
}
};
int main() {
try {
B b;
C c;
// Changes to A by using templates and passing the object      
// above to A's explicit constructor
A<B> a1( b );
A<C> a2( c );
// Notice the syntax on how to assign the function pointer.
a1.func = &B::func;
a2.func = &C::func;
// using the operator() to invoke the function pointer.
a1();
a2();
} catch( std::runtime_error& e ) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;    
}

-输出-

2
6

最新更新