C++ 将一个类的方法作为参数传递给C+中的另一个类+;
我的一般目的是设计一个优化器。它是一个为给定函数搜索最大值的类。我打算在代码的其他部分(包括其他类的方法)中使用此优化器 我实现了如下的优化器:C++ 将一个类的方法作为参数传递给C+中的另一个类+;,c++,C++,我的一般目的是设计一个优化器。它是一个为给定函数搜索最大值的类。我打算在代码的其他部分(包括其他类的方法)中使用此优化器 我实现了如下的优化器: class MyOptimizer { public: typedef double (*FuncType)(double); MyOptimizer(FuncType f, double a, double b) : _f(f), _a(a), _b(b) {} double optimize() const {
class MyOptimizer {
public:
typedef double (*FuncType)(double);
MyOptimizer(FuncType f, double a, double b) : _f(f), _a(a), _b(b) {}
double optimize() const {
// do something with _f in order to find the maximum
return maximum;
}
private:
double _a;
double _b;
FuncType _f;
}
我想在我的其他代码片段中将优化器用作库。例如:
class AnyClass {
public:
...
double func(double x) const {
// using members of the instance
}
void aMethod() {
MyOptimizer opt(func, 0.0, 1.0);
double bestArgument = opt.optimize();
}
...
};
但是我不允许这样做,因为AnyClass::func
的类型签名不同
设计优化器以便于在其他代码段中使用的最佳方法是什么?如能提供代码示例,将不胜感激
我需要一个C++ 1998/2003标准的解决方案。< /p> C++ 11解决方案(对其编辑之前的问题):
问题是AnyClass::func
实际上需要两个参数,形式上是x
,但它也需要this
。如果您负担得起C++11,您的朋友是否在这里(或可调用的模板):
如果没有,则需要编写自己的包装器类来存储this
的值,并公开操作符()
,并传递这样的对象而不是函数指针
C++03解决方案:
然后,您可以将其用于非静态函数:
// within AnyClass
AnyClassWrapper<AnyClass> callable(this, &AnyClass::f);
MyOptimizer opt(callable, 0.0, 1.0);
// anywhere
MyOptimizer opt2(std::sin, 0.0, 1.0);
请注意,以上内容基本上实现了lambda函数在幕后所做的工作。如果需要,您可以类似地将std::function
后传,这样优化器就不需要任何模板。如果您可以选择更改MyOptimizer
,请将其更改为类模板或使用std::function
而不是函数指针
如果您不能选择更改MyMonitor
,我有几点建议
要将AnyClass::func
与MyOptimizer::optimize
一起使用,您需要一个非成员函数或静态
成员函数。如果这些函数能够访问要调用其上的func
的AnyClass
对象,则它们都可以工作
使用非成员函数
// Global variable
AnyClass* currentAnyClass = nullptr;
// Non-member function
double funcWrapper(double x)
{
assert(currentAnyClass != nullptr);
return currentAnyClass->fun(x);
}
然后
void aMethod() {
currentAnyClass = this;
MyOptimizer opt(funcWrapper, 0.0, 1.0);
double bestArgument = opt.optimize();
currentAnyClass = nullptr;
}
使用静态
成员函数
// Global variable
AnyClass* currentAnyClass = nullptr;
// Non-member function
double funcWrapper(double x)
{
assert(currentAnyClass != nullptr);
return currentAnyClass->fun(x);
}
它遵循几乎相同的策略。与第一次相比,我更喜欢它,因为它将currentAnyClass
和funcWrapper
保留在`AnyClass'的范围内
class AnyClass {
public:
...
double func(double x) const {
// using members of the instance
}
void aMethod() {
currentAnyClass = this;
MyOptimizer opt(funcWrapper, 0.0, 1.0);
double bestArgument = opt.optimize();
currentAnyClass = nullptr;
}
static AnyClass* currentAnyClass;
static double funcWrapper(double x)
{
assert(currentAnyClass != nullptr);
return currentAnyClass->func(x);
}
};
AnyClass* AnyClass::currentAnyClass = nullptr;
最简单的解决方案是让AnyClass从优化器继承。比如:。
但是如果你死掉了回调,你应该知道你的C++声明有错误。我会对你的问题发表评论,而不是发表答案,但是斯塔科夫。需要至少50名代表才能发表评论 您可以使用指向成员的指针函数。这是一个很好的描述
这里是一个实现
template <class T>
class MyOptimizer {
public:
typedef double (T::*FuncType)(double) const;
MyOptimizer(T* instance, FuncType f, double a, double b) : _instance(instance),_f(f), _a(a), _b(b) {}
double optimize() const {
// do something with _f in order to find the maximum
return 1.0;
}
private:
double _a;
double _b;
FuncType _f;
T* _instance;
};
class AnyClass {
public:
double func(double x) const {
// using members of the instance
return 0.0;
}
void aMethod() {
MyOptimizer<AnyClass> opt(this, &AnyClass::func, 0.0, 1.0);
double bestArgument = opt.optimize();
}
};
模板
类优化器{
公众:
typedef double(T::*FuncType)(double)const;
MyOptimizer(T*实例,函数类型f,双a,双b):_实例(实例),_f(f),_a(a),_b(b){}
双优化()常量{
//用_f做点什么以找到最大值
返回1.0;
}
私人:
双a;
双b;
FuncType _f;
T*_实例;
};
类任意类{
公众:
双函数(双x)常数{
//使用实例的成员
返回0.0;
}
void-aMethod(){
MyOptimizer opt(this,&AnyClass::func,0.0,1.0);
double bestArgument=opt.optimize();
}
};
很抱歉,我在以前的回答中没有注意到C++03的要求。我会写一个新的。@没问题,C++11的解决方案看起来很短,很好。如果我对一个普通函数使用MyOptimizer
,而不是对一个类的成员使用,它会如何工作?我想在我的项目中的任何地方都使用MyOptimizer
。这不是一个好的解决方案。在多线程的情况下,它会破坏封装并失败。@Fomalhaut,关于多线程,您提出了一个很好的观点。但是,如果OP没有更改MyOptimizer
的选项,是否有更好的替代方案?
void aMethod() {
currentAnyClass = this;
MyOptimizer opt(funcWrapper, 0.0, 1.0);
double bestArgument = opt.optimize();
currentAnyClass = nullptr;
}
class AnyClass {
public:
...
double func(double x) const {
// using members of the instance
}
void aMethod() {
currentAnyClass = this;
MyOptimizer opt(funcWrapper, 0.0, 1.0);
double bestArgument = opt.optimize();
currentAnyClass = nullptr;
}
static AnyClass* currentAnyClass;
static double funcWrapper(double x)
{
assert(currentAnyClass != nullptr);
return currentAnyClass->func(x);
}
};
AnyClass* AnyClass::currentAnyClass = nullptr;
template <class T>
class MyOptimizer {
public:
typedef double (T::*FuncType)(double) const;
MyOptimizer(T* instance, FuncType f, double a, double b) : _instance(instance),_f(f), _a(a), _b(b) {}
double optimize() const {
// do something with _f in order to find the maximum
return 1.0;
}
private:
double _a;
double _b;
FuncType _f;
T* _instance;
};
class AnyClass {
public:
double func(double x) const {
// using members of the instance
return 0.0;
}
void aMethod() {
MyOptimizer<AnyClass> opt(this, &AnyClass::func, 0.0, 1.0);
double bestArgument = opt.optimize();
}
};