Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将一个类的方法作为参数传递给C+中的另一个类+;_C++ - Fatal编程技术网

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();
    }
};