-5

Please check the following code. Why it is wrong and how to fix? Thank you.

class A
{
  public:

    class B
    {
      public:
        B(int(*cf)())
        {
            f = cf;
        }

        int (*f)();
    };


    B *b;


    A()
    {
        b = new B(this->a);
    }


    int a()
    {
    }
};

int main()
{
    A a;
}

compilation error:

user180574
  • 5,681
  • 13
  • 53
  • 94

2 Answers2

1

If you absolutely need to call a function by pointer you will need to use a pointer to member function instead of a pointer to function. A pointer to member function has a different declaration syntax that includes the class type the function belongs to. In your case the parameter declaration would look like int (A::*cp)(). You will also need to change the declaration of the f member variable to int (A::*f)().

In order to call a pointer to member function you need to have a pointer to an object of the type the function belongs to. You also need to use one of the pointer to member operators; ->* or .*

void call(A* c, int (A::*f)())
{
    (c->*f)(); // call member function through pointer
}

The extra set of parenthesis is required due to the order of precedence of operators.

The following code includes the changes necessary for you to use pointer to member functions.

class A
{
public:

    class B
    {
    public:

        // Take a pointer to member function.
        B(int(A::*cf)())
        {
            f = cf;
        }

        void call(A* c)
        {
            (c->*f)();
        }

        int (A::*f)();  // pointer to member function
    };


    B *b;


    A()
    {
        b = new B(&A::a);
    }


    int a()
    {
        return 0;
    }
};

int main()
{
    A a;
    a.b->call(&a);
}

I also recommend that you consider using std::function and std::bind (or their Boost equivalents if you do not have a C++11 compiler).

Captain Obvlious
  • 19,754
  • 5
  • 44
  • 74
0

Do not use function pointers in the first place when using C++.

There is an easier and more elagant solution - an interface.

i.e.

class Interface {
   public:
      virtual int CallMe() = 0;
};

class B : public Interface { int CallMe() { return 5; };

class A : public Interface {
   private:

      Interface *m_i = 0;

   public:

      A(Interface *i) : m_i(i) { }
      A() : m_i(this) { };

      void DoIt() { cout << m_i->CallMe() << endl; }

      int CallMe() { return 8; }
};

int main() {
   A a(new B); // Coult be any object that implements Interface (as yes it is a memory leak
   A aa();
   a.DoIt(); // Will print 5
   aa.DoIt(); // WIll print 8
   return 0;
}
Ed Heal
  • 59,252
  • 17
  • 87
  • 127
  • You basically move the function to class B. While what I need is to call from B a function in A. – user180574 Jun 27 '13 at 18:15
  • Shouldn't that be `class B { Interface *i_; public: B(Interface *i) : i_(i) {} int CallMe() { return i_->CallMe(); } };` ? – Captain Obvlious Jun 27 '13 at 18:27
  • @CaptainObvlious - Both class A and B implement the virtual function `CallMe`. Class A records (`m_i`) a pointer to the interface. The `DoIt` method calls the `CallMe` method for the interface `m_i` – Ed Heal Jun 27 '13 at 18:32