C :铸造成员功能指针
C++: Casting Member Function Pointer
在以下程序中,如何将bar键入foo?
#include <iostream>
namespace NA {
class A {
public:
int (*foo)(int);
};
}
namespace NB {
class B : public NA::A {
public:
int bar(int i) {
std::cout << i << std::endl;
return i*2;
}
B() {
this->foo = bar; // how to type cast this fn pointer?
}
};
}
int main() {
NA::A *a = new NB::B();
std::cout << a->foo(2) << std::endl;
}
我尝试了如下打字,但是当我运行程序时会出现严重错误:
B() {
typedef int (*TypeFoo)(int);
this->foo = reinterpret_cast<TypeFoo> (&bar);
}
这是我运行时的结果:
$ ./a.out
31947824
63895648
我期待2和4。
更新:在看到回答表明没有解决上述问题的解决方案之后,我将通过我试图解决的具体问题进一步更新此问题。
请参阅https://boringssl.googlesource.com/boringssl//head/head/include/include/openssl/ssl.h#1173-我试图拥有struct struct ssl_private_keykey_method_method_st _ST em> ssl_private_private_private_private在不同的私钥上操作。我试图让另一个struct从 ssl_private_key_method_st 中继承,并具有 sign/decrypt/complete 方法在继承struct的实例变量上运行。
我知道使用 ssl_ [sg] et_ex_data 间接地将数据传递到这些函数,但是我正在寻找一种更简单/直接的方法,将实例数据传递到这些函数时。<<<<<<<<<<<<<<<<<<<<<<<<<<<</p>
您正在遇到未定义的行为。
TypeFoo
和bar
是不同类型的功能指针(分别为int (*)(int)
和int (NB::B::*)(int)
(。 虽然可以将一个施放给另一个,但使用结果调用该函数将导致不确定的行为。
8.2.10 retinterpret cast [expr.reinterpret.cast]
...
6.可以将功能指针明确转换为其他类型的功能指针。[注意:通过指针调用功能类型(11.3.5(的函数的效果与函数定义中使用的类型不同。 - end Note Note]除了将"指针"类型的PRVALUE转换为" To To To To to T2"的类型(其中T1
和T2
是函数类型(,然后返回其原始类型产生原始指针值,此类指针转换的结果未指定。。[注意:另请参见7.11。 指针转换的详细信息。 - 末尾注]
简短答案:您不。
非静态成员功能指针很奇怪。调用一个涉及一个秘密this
参数,它们可能是virtual
。这使它们无法与普通功能指针混合。
您应该考虑使用std::function<int(int)>
而不是int (*)(int)
。这将使您可以存储以下lambda之类的东西:
B(){
std::function<int(int)> myfn = [this](int x){
return bar(x);
};
}
此lambda通过参考捕获当前对象,此引用存储在std::function
对象本身内。但是,您可以直接或通过lambda或绑定表达式将任何其他功能分配给std::function
。
另一方面,如果您的bar
方法实际上并不取决于实例,则只需将其制作static
即可。这将允许它与常规功能指针混合,因为它不再需要秘密this
,并且不能为virtual
。
static int bar(int i) {
std::cout << i << std::endl;
return i*2;
}
这样写,可以将&B::bar
分配给常规int (*)(int)
功能指针。
您的TypeFoo
定义了指向常规功能的指针,而bar
是一种方法。每个非静态方法都有一个隐式的第一个参数this
。
因此,您应该确定您需要什么:常规功能(在这种情况下是bar
静态(或一种方法,在这种情况下,您应该这样打字:
typedef int (B::*TypeFoo)(int);
reinterpret_cast
是一个易于实践的练习。如果您不能没有它 - 代码不正确的可能性很高。
调用成员函数指针是真正的痛苦。我建议您采用以下方式进行此操作,简化了许多上下文处理:
#include <iostream>
namespace NA {
class A {
public:
int (A::*foo)(int);
};
}
namespace NB {
class B : public NA::A {
public:
int bar(int i) {
std::cout << i << std::endl;
return i*2;
}
int callFoo(int x) {
return (this->*foo)(x);
}
B() {
this->foo = (int(A::*)(int)) (&B::bar);
}
};
}
int main() {
NA::A *a = new NB::B();
std::cout << ((NB::B*)a)->callFoo(2) << std::endl;
}
- 如何定义和设置指向模板类方法的功能指针
- 将状态传递给功能指针
- 如何使用结构内的功能指针调用私有函数
- 功能指针不起作用(C )
- 将C 方法作为功能指针传递
- 优化调用一系列功能指针
- C 功能指针和成员功能指针
- 当直接分配时,为什么此功能指针分配起作用,而不是与有条件的操作员一起使用
- 功能指针的静态初始化
- 功能指针参数参数转换为const
- 使用lambda在功能指针铸造时双免费
- 如何在两个类之间使用功能指针
- exc_bad_access on for loop(数组功能指针)
- 如何通过功能指针调用派生方法
- 虚拟功能指针指向派生类中的函数
- C :铸造成员功能指针
- 指向成员功能的功能指针
- 正确施放以指向返回功能的函数的功能指针
- 当用作模板参数时,功能指针是否需要指向具有外部链接的函数
- 在堆中创建功能指针的数组