指向c ++中的类方法的指针

时间:2017-12-08 16:20:56

标签: c++ function-pointers

A有很多B类,A类有一个对象b。这个对象b有一个函数(calc)需要一个指向A对象中方法的指针。这个方法(有趣)在类中访问私有变量(在我的例子中只返回3)。

class A;

class B {
public:
  virtual int calc ( int (A::*fun)())  {    return 2*fun();  };
};

class A {
  B* b;

public:
  A (B* b_) : b (b_) {};
  int fun() { return 3; };
  int run(){ return b->calc(&A::fun); };
};

int main() {
  B* b = new B();
  A a(b);
  a.run();
  return 0;
}

如何在B类calc方法的定义中正确使用指向方法的指针?

我收到此错误消息:

teste.cpp:10:58: error: must use ‘.*’ or ‘->*’ to call pointer-to-member     function in ‘fun (...)’, e.g. ‘(... ->* fun) (...)’
   virtual int calc ( int (A::*fun)())  {    return 2*fun();  };
                                                      ^

4 个答案:

答案 0 :(得分:1)

如果您对std::function方法可行,我建议使用A方法。但是,为了完整起见,以下是如何正确使用指针到成员函数的方法。

指向成员的指针本身并不存储"当前" ->*的实例,因此您需要明确传递它。然后使用特殊的.*(或virtual int calc (A* value, int (A::*fun)()) { return 2 * (value->*fun)(); }; )语法来调用它。

b->calc(this, &A::fun);

然后你将其称为me.filter

答案 1 :(得分:1)

您可以按照自己的方式执行此操作,但成员函数在特定实例上必须为called

class A;

class B {
public:
    virtual int calc(A* a, int (A::*fun)()) { return 2 * (a->*fun)(); };
};

class A {
    B* b;

public:
    A(B* b_) : b(b_) {};
    int fun() { return 3; };
    int run() { return b->calc(this, &A::fun); }; // now also passing this pointer
};

int main() {
    B* b = new B();
    A a(b);
    a.run();
    return 0;
}

如果没有calc()是虚拟的,那么lambda也是一个选项:

class A;

class B {
public:
    template<typename T>
    int calc(T fun) { return 2 * fun(); };
};

class A {
    B* b;

public:
    A(B* b_) : b(b_) {};
    int fun() { return 3; };
    int run() {
        return b->calc([this]() {return fun(); } );
    };
};

int main() {
    B* b = new B();
    A a(b);
    a.run();
    return 0;
}

答案 2 :(得分:0)

如果您能够使用C ++ 11,那么您应该使用std::functionstd::bind:否则您需要使用pointer to member function +指向该实例的指针。

使用C ++ 11

#include <functional>

class B {
public:
  virtual int calc (std::function<int()>&& fun) { return 2 * fun();  }; };
};

class A {
  B* b;

public:
  A (B* b_) : b (b_) {};
  int fun() { return 3; };
  int run() { return b->calc(std::bind(&A::fun, this)); };
};

没有C ++ 11

class B {
public:
  virtual int calc (int(A::*fnptr)(), A* a) { return 2 * (a->*fnptr)(); };
};

class A {
  B* b;

public:
  A (B* b_) : b (b_) {};
  int fun() { return 3; };
  int run() { return b->calc(&A::fun, this); };
};

参见示例here

答案 3 :(得分:0)

定义指针类方法并将其初始化为(假设SomeFn与签名匹配):

PROCEDURE centroId(pnombre IN VARCHAR2) IS
    geomEntrada SDO_GEOMETRY;
    dist VARCHAR2(100);
    tupla caceres%ROWTYPE;
    dim SDO_DIM_ARRAY;
    -- Cursor para recuperar los barrios
    CURSOR cursor_barrio IS 
      SELECT *
      FROM caceres
      WHERE tipo = 'Barrio';

  BEGIN

    -- Recuperar la geometria del parametro de entrada
    SELECT Geom INTO geomEntrada
    FROM Caceres
    WHERE Nombre = pnombre;

    -- Obtener dim
    SELECT DIMINFO INTO dim
    FROM USER_SDO_GEOM_METADATA
    WHERE table_name='CACERES'; --Ojo, CACERES en mayúsculas

    -- Recorrer todos los barrios
    OPEN cursor_barrio;
    LOOP
      FETCH cursor_barrio INTO tupla;
      EXIT WHEN cursor_barrio%NOTFOUND;

      --SDO_GEOM.SDO_LENGTH
      dist := SDO_GEOM.SDO_CENTROID(geomEntrada,dim);
    END LOOP;
    DBMS_OUTPUT.PUT_LINE(pnombre||' have this center: ' || dist);

  END centroId;

被称为:

RetType (ClassName::*pfn)(Args) = &ClassName::SomeFn;