无法将 shared_ptr 参数传递给函数指针
Cannot pass shared_ptr argument to function pointer
我对使用带有 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的ownership有关,但我不熟悉智能指针,我完全不知所措。
我想知道
- 为什么它不起作用
- 如何让它发挥作用
限制是
- w/o 改变
print_int
函数本身
- 在
FuncWrapper<T>::execFunction
内执行函数
FuncWrapper<T>::execFunction
必须是静态的
其他情况随意更改。 (在 ClassA
构造函数内部,在 main
execFunction
等内部)
问题不在于 shared_ptr,而是指向函数和成员函数的指针不匹配。
您的函数包装器需要一个指向函数的指针 (void (*)(std::shared_ptr<int>)
),但您提供了一个指向成员函数 (void (ClassA::*)(std::shared_ptr<int>)
) 的指针,这是不同的。添加了一个指向 this 的指针的隐式前导参数。
真实情况是这样的:
// 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
我对使用带有 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的ownership有关,但我不熟悉智能指针,我完全不知所措。
我想知道
- 为什么它不起作用
- 如何让它发挥作用
限制是
- w/o 改变
print_int
函数本身 - 在
FuncWrapper<T>::execFunction
内执行函数
FuncWrapper<T>::execFunction
必须是静态的
其他情况随意更改。 (在 ClassA
构造函数内部,在 main
execFunction
等内部)
问题不在于 shared_ptr,而是指向函数和成员函数的指针不匹配。
您的函数包装器需要一个指向函数的指针 (void (*)(std::shared_ptr<int>)
),但您提供了一个指向成员函数 (void (ClassA::*)(std::shared_ptr<int>)
) 的指针,这是不同的。添加了一个指向 this 的指针的隐式前导参数。
真实情况是这样的:
// 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