Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 指向非静态成员函数代码的指针不';不行?_C++_Function_Class_Pointers_Member - Fatal编程技术网

C++ 指向非静态成员函数代码的指针不';不行?

C++ 指向非静态成员函数代码的指针不';不行?,c++,function,class,pointers,member,C++,Function,Class,Pointers,Member,这就是我想做的: class A { public: void(*fPtr)(); }; class B { int ib = 2; public: void memf() { printf("ib = %i\n", ib); } }; class C { int ic = 6; public: void memf() { printf("ic = %i\n", ic); } }; int main()

这就是我想做的:

class A {
public:
    void(*fPtr)();
};

class B {
    int ib = 2;
public:
    void memf() {
        printf("ib = %i\n", ib);
    }
};

class C {
    int ic = 6;
public:
    void memf() {
        printf("ic = %i\n", 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
我知道这看起来像是复制品,也许是。我未能使用建议的解决方案,如使用

有人能告诉我怎么做才能让我明白我做错了什么吗? 我也想知道为什么标准方法不起作用

换句话说:更正我的代码;)
我非常感谢。

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

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


本网站上的其他答案应该能够提供一些关于解决此问题的可能策略的信息,但希望这能从一开始就说明问题所在。

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

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


本网站上的其他答案应该能够提供一些关于解决此问题的可能策略的信息,但希望这能为解决此问题提供一些线索。

以下是解决您问题的可能方法:不过,我做了一些小改动

  • 第一个-我将
    A类
    更改为
    类模板
  • 第二个-我添加了一个指向类型
    的指针作为类成员
  • 第三个-我在
    A
    中添加了一个
    operator()()
    来调用函数调用
  • 第四,为了保持一致,我更改了函数指针的名称和其他类函数的名称
  • 第五,我没有使用
    printf()
    ,而是使用
    std::cout
下面是修改后的代码的样子:阅读注释以了解其工作原理


这里有一个可能解决你问题的方法:不过我做了一些小小的改变

  • 第一个-我将
    A类
    更改为
    类模板
  • 第二个-我添加了一个指向类型
    的指针作为类成员
  • 第三个-我在
    A
    中添加了一个
    operator()()
    来调用函数调用
  • 第四,为了保持一致,我更改了函数指针的名称和其他类函数的名称
  • 第五,我没有使用
    printf()
    ,而是使用
    std::cout
下面是修改后的代码的样子:阅读注释以了解其工作原理


还有关于指向成员函数的指针的更多信息:
a.fPtr
是指向类
a
的成员的指针
b.memf
c.memf
(或者更准确地说,正如警告所说,
&b.memf
&c::memf
)不是类
A
的成员指针。指向成员的指针特定于其类。除非类
A
包含指向类
B
和类
C
指针的成员,否则无法更正它-您尝试执行的操作有缺陷。有关指向成员函数的指针的更多信息:
A.fPtr
是指向类
A
成员的指针
b.memf
c.memf
(或者更准确地说,正如警告所说,
&b.memf
&c::memf
)不是类
A
的成员指针。指向成员的指针特定于其类。除非类
A
包含指向类
B
和类
C
的指针的成员,否则无法更正它-您尝试执行的操作有缺陷。我知道这是如何工作的。。。谢谢你给我看。虽然不幸的是(我在问题中没有具体说明),我不能以那种方式使用普通函数。我需要考虑一下。我知道这是怎么回事。。。谢谢你给我看。虽然不幸的是(我在问题中没有具体说明),我不能以那种方式使用普通函数。我需要考虑一下。是的,我现在明白了。我想知道,有没有办法在函数中存储变量?类似于函数中的静态变量。如果我没有误解它们的工作原理。编辑:别担心,那是行不通的。我找到了一条路!是的,我现在明白了。我想知道,有没有办法在函数中存储变量?类似于函数中的静态变量。如果我没有误解它们的工作原理。编辑:别担心,那是行不通的。我找到了一条路!
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