0

我是指向成员函数的新手,我想知道它们的优缺点。

具体来说,考虑一下:

#include <iostream>
#include <list>

using namespace std;

class VariableContainer;

class Variable
{
public:
  Variable (int v) : value (v), cb_pointer (0) {}
  ~Variable () {}

  void SetCallback (void (VariableContainer::*cb)(int)) {
    cb_pointer = cb;
  }
  void FireCallback (void) {
    /* I need a reference to a VariableContainer object! */
  }

private:
  int value;
  void (VariableContainer::*cb_pointer) (int);
};

class VariableContainer
{
public:
  VariableContainer () {}
  ~VariableContainer () {}

  void AddVar (Variable &v) {
    v.SetCallback (&VariableContainer::Callback);
  }
  void Callback (int v) { cout << v << endl; }
};

int main ()
{
  Variable v (1);
  VariableContainer vc;

  vc.AddVar (v);
  v.FireCallback();

  return 0;
}

如评论中所述,要触发回调 ( FireCallback),我需要对现有VariableContainer对象的一些引用,该对象应作为VariableContainer::AddVar (...). 现在:

  1. 我应该使用指向成员函数的指针吗?或者我应该直接调用Callback (...)(因为我有一个指向VariableContainer对象的指针)?
  2. 每种解决方案的优缺点是什么?

蒂亚,吉尔

4

2 回答 2

2

根据未来的变化,您可以决定:

  • 变量的 FireCallback 将调用其他函数 => 指向 mf 的指针可能有用,但其他机制更 c++ish
  • 只有“回调”函数会被调用 => 坚持arg->CallBack()直接调用。

该问题的一个可能解决方案是使用接口层:这只不过是观察者模式的一种实现。这有点面向对象,因此很冗长,但语法更容易。

class Observer {
public:
    virtual ~Observer(){};
    virtual void callback( int v ) = 0;
};

// actual implementation
class MyCallbackObserver : public Observer {
    virtual void callback( int v ) { std::cout << v << std::endl; }
    void some_other_method( int v ) { std::cout << "other " << v ; }
};

你的Variable班级会有一个装满观察者的容器:

class Variable {
public:
   std::vector<Observer*> observers; // warning: encapsulation omitted
   void FireCallback(){
      // assuming C++ 0x
      for( auto it : observers ) {
        (*it)->Callback( value );
      }
   }

如果需要在同一个对象上调用其他函数,您可以引入一个包装器:

class OtherCaller: public Observer {
 public:
     MyObserver* obs;
     virtual void callback( int v ) { obs->some_other_method( v ); }
}

并将其添加到集合中:

Variable var;
MyObserver m;
OtherCaller mo;
mo.obs = &m;

var.observers.push_back(&m);
var.observers.push_back(&mo);

var.FireCallback();
于 2010-07-14T14:10:46.103 回答
1

这取决于您在这里的需求。

如果你只有一个回调函数,而且你总是知道它的名字,那还不如直接调用它。它更简单,更容易理解,并且不涉及额外的变量。

如果您需要根据配置调用多个回调之一的能力,则成员函数指针会很有用:您可以将回调成员函数指针设置为您希望调用的实际回调,然后用于选择要执行的回调.

于 2010-07-14T13:28:03.190 回答