Mike Warren Mike Warren - 5 months ago 18
C++ Question

Pointers to member functions of another object

My situation is thus:
I have two classes: A,B. A contains

, and B requires function pointer from A to initialize its own operations.

(I am trying to implement the integer group and integer ring mathematical structures in c++)

What is the safest way to accomplish this? (I learned that giving B a pointer to A causes unexpected behaviour in A. I tried it here. )

Now that I am at my computer, I shall post my codebase (I made B member class to A, so as to minimize the sections I have to type up):


#ifndef A_H
#define A_H

#include <vector>

class A
static int defaultMultiply(int, int);
int multiply(int, int);
class B
typedef int(*defaultMultiplication)(int, int);
typedef int(A::*multiplication)(int, int);
B(int, int, multiplication);
B operator*(const B&);

int m, parentGroupSize;
multiplication mult;
defaultMultiplication defMult;

int n;
std::vector<A::B> elements;




#include "A.h"

#include <new>



A::A(int n)
: n(n), elements(std::vector<A::B>(n))


int A::defaultMultiply(int x, int y) { return (x * y); }
// special multiplication: integer groups have integer addition modulo the group size as their multiplication
int A::multiply(int x, int y)
int a = x % this->n, b = y % this->n;
if (a < 0) a += this->n;
if (b < 0) b += this->n;
return ((a + b) % n);

: m(0),
defMult(&A::defaultMultiply) // right?


A::B::B(int m, int n, multiplication mult)
: parentGroupSize(n), mult(mult), defMult(0)
// this->m must be in [0, g->size() - 1], if n is larger than 1
if (n > 1)
this->m = m % n;
if (this->m < 0) this->m = n + this->m;
this->m = m;

A::B A::B::operator*(const A::B& b)
if (this->parentGroupSize == b.parentGroupSize)
if (this->mult)
return A::B::B((this->*mult)(this->m, b.m), this->parentGroupSize, &A::B::mult); // I tried using this->mult for last argument, but it wouldn't take it
return A::B(); // or something similar

int A::B::val() const { return this->m; }


#include <iostream>

#include "A.h"

using namespace std;

int main()
A(26); // didn't implement any methods to get B's from A, since I am merely testing compilation. I'm trying for that ever-elusive MCVE with just this...

Oh, I also get the following error:
error: pointer to member type 'int (A::)(int, int)' incompatible with object type 'A::B'


Your problem isn't that you're passing a member-function (as an argument) to the constructor of an object of a different type than the member-function class type; the problem is that you're calling the member function with the wrong type. The compiler error you're getting is actually quite clear on this: a pointer-to-member must be used with the same class-type for which it was declared, because otherwise it would be meaningless.

Note that inner classes are not derived classes; a B object is not a specialized type of A. (I think you already realize this, but I want to be clear.) So when you try to invoke a method of A with an object-instance of type B, you have asked for something that is completely nonsensical.

So, there are two options:

  • Use pointer-to-member-of-B instead of pointer-to-member-of-A. There's never any reason to invoke the members with objects of type A, so it's unclear why you thought a pointer-to-member-of-A would be useful here.
  • Use non-member pointers. Note that your defaultMultiplication type already is a non-member function. Note that non-members can still take instances of B as arguments; they just have a much simpler syntax.