如何获得指向成员函数的函数指针



我正在做一个项目,我需要涉及到函数指针,更具体地说,是指向成员函数的函数指针。我几乎阅读了所有相关的问题,但是没有一个是描述我的具体问题的。所以,我将试着用一个简单的例子来描述我的问题。

让我们假设我有三个不同的头文件和不同的类,如下所示:

foo1.h

struct Foo1{
int a1;
double b1;

void (Foo2::*fp)(const double);
}

foo2.h

#include "foo1.h"
class Foo2{
public:
void print_foo2(const double p){
cout << "From Foo2: " << p << endl;
}

Foo1 foo1;
}

foo3.h

class Foo3 : public Foo2{
Foo1 foo1;

foo1.fp = &Foo2::print_foo2; // cannot do that
}

因此,结构体Foo1的成员变量之一是指向Foo2的成员函数print_foo2的函数指针。出于这个原因,我创建了对象foo1的实例,并为它分配了一个指向print_foo2的指针。类Foo3继承自类Foo2

我注意到,正如我所想,它可能是解决问题的有用信息。但是,我无法获得指向函数的指针,因为Foo2在结构体Foo1中无法识别。即使在foo1.h中包含foo2.h也无济于事。如果我没有弄错的话,这是因为Foo1在构造过程中需要Foo2作为其成员变量,但以同样的方式Foo2需要构造Foo1。因此,这会导致死锁。

这是问题的原因吗?如果是,我该如何解决?

既然Foo2Foo3都需要Foo1的定义,那么它们都应该是#include "foo1.h"。如果没有Foo1的定义,编译器将无法计算Foo2Foo3的大小。

另一方面,Foo1不需要Foo2的定义,因此可以转发声明Foo2来解决死锁。无论如何定义Foo2,它保留的指针(fp)将具有相同的大小,这就是为什么前向声明足够了。

评论内联:

// foo1.h
#pragma once
class Foo2;       // forward declaration
struct Foo1{
int a1;
double b1;

void (Foo2::*fp)(const double);
};
// foo3.h
#pragma once
#include "foo2.h"
#include "foo1.h" // not strictly needed since `foo2.h` includes it
class Foo3 : public Foo2{
// proper initalization:
Foo1 foo1{1, 3.141, &Foo2::print_foo2};
};

注意:在代码中,Foo2Foo3都有一个Foo1成员变量。这意味着Foo3总共有2个。如果您在Foo3中只有一个一个Foo1,而希望Foo3在继承的Foo2中初始化Foo1,则可以从Foo3中删除Foo1成员并初始化基类(Foo2),如下所示:

class Foo3 : public Foo2{
public:
Foo3() : Foo2{1, 3.141, &Foo2::print_foo2} {}
};

相关内容

  • 没有找到相关文章

最新更新