如何解决无法将shared_ptr参数传递给函数指针
我对使用带有shared_ptr参数的函数指针的代码有疑问。
这是示例代码。
header.h
#include <functional>
#include <iostream>
template <class T> class FuncWrapper{
private:
void (*original_function)(T a);
public:
void setFunction(void *func);
void execFunction(T a,void *data);
};
template <class T> void FuncWrapper<T>::setFunction(void *func){
original_function = (void (*)(T))func;
}
template <class T> void FuncWrapper<T>::execFunction(T a,void *data){
FuncWrapper<T>* wrapper = (FuncWrapper<T>*)data;
std::cout << "inside wrapper " << *(a.get()) << std::endl;
wrapper->original_function(a);
}
main.cpp
#include <iostream>
#include <memory>
#include "header.h"
class ClassA{
public:
ClassA(std::shared_ptr<int> a){
FuncWrapper<std::shared_ptr<int>> *fw;
fw = new FuncWrapper<std::shared_ptr<int>>;
fw->setFunction((void*)&ClassA::print_int);
std::function<void(std::shared_ptr<int>)> g = std::bind(&FuncWrapper<std::shared_ptr<int>>::execFunction,fw,std::placeholders::_1,fw);
g(a);
delete fw;
}
private:
void print_int(std::shared_ptr<int> x) {
std::cout << "printing int" << std::endl;
std::cout << "given int " << *(x.get()) << std::endl;
}
};
int main(int argc,char * argv[]){
std::shared_ptr<int> x = std::make_shared<int>(10);
std::cout << "inside main " << *(x.get()) << std::endl;
ClassA *temp;
temp = new ClassA(x);
delete temp;
return 0;
}
结果
inside main 10
inside wrapper 10
printing int
Segmentation fault (core dumped)
我不知道为什么会导致细分错误。
将std::shared_ptr<int>
更改为int
很好。
因此,我认为这与shared_ptr的所有权有关,但是我对智能指针并不熟悉,我完全不知所措。
我想知道
- 为什么不起作用
- 如何使其发挥作用
限制是
- 不更改
print_int
函数本身 - 在
FuncWrapper<T>::execFunction
内执行函数 -
FuncWrapper<T>::execFunction
必须是静态的
否则,可以自由更改。 (在ClassA
构造函数内部,在main
execFunction
内部等等)
解决方法
问题不是shared_ptr,而是函数指针和成员函数的指针不匹配。
您的函数包装器需要一个指向函数(void (*)(std::shared_ptr<int>)
)的指针,但是您提供了一个指向成员函数(void (ClassA::*)(std::shared_ptr<int>)
)的指针,这是不同的。一个指向该指针的隐式前导参数被添加到其中。
这是真正的样子:
// pointer to member function
void (*)(ClassA *ptr,std::shared_ptr<int>)
您的shared_ptr转到第一个参数,幸运的是,应用程序出现了段错误。
解决方案之一是使函数print_int
静态。
class ClassA{
public:
ClassA(std::shared_ptr<int> a){
FuncWrapper<std::shared_ptr<int>> *fw;
fw = new FuncWrapper<std::shared_ptr<int>>;
fw->setFunction((void*)&ClassA::print_int);
std::function<void(std::shared_ptr<int>)> g = std::bind(&FuncWrapper<std::shared_ptr<int>>::execFunction,fw,std::placeholders::_1,fw);
g(a);
delete fw;
}
private:
static void print_int(std::shared_ptr<int> x) {
std::cout << "printing int" << std::endl;
std::cout << "given int " << *(x.get()) << std::endl;
}
};
但是您的代码中似乎还有另一个问题。函数指针不应转换为对象指针(void *是)。也许可以这样改变您的setFunction:
void setFunction(void (*func)(T)) {
original_function = func;
}
有关here
的更多信息版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。