Given two classes: X and Y. X contains a member of type Y * and passes the pointer to its member function to the instance of Y. So in C++ it looks like this:
x.h
#pragma once
class Y;
class X
{
public:
    X();
private:
    Y *y;
    void myfunc(int);
};
x.cpp
#include "x.h"
#include "y.h"
X::X()
{
    this->y = new Y(*this, &X::myfunc);
}
void X::myfunc(int dummy)
{
    dummy = dummy;
}
y.h
#pragma once
//#include "x.h"    // this would fix the issue!
class X;
class Y
{
public:
    Y(X &x, void (X::*pMyCallback)(int));
    ~Y();
private:
    X &x;
    void (X::*pMyCallback)(int) = nullptr;
};
y.cpp
#include "y.h"
#include "x.h"
Y::Y(X &x, void (X::*pMyCallback)(int))
    : x(x), pMyCallback(pMyCallback)
{
    (x.*pMyCallback)(3);
}
Y::~Y()
{
}
When I run this code, Visual Studio 2015 raises the exception: "MYPROGRAM.exe has triggered a breakpoint". Sometimes it crashes with Access Violation exception.
int main(int argc, char *argv[])
{
    X x;
    return 0;
}
It has come to my notice that the issue is somehow related to compilation units as it doesn't crash if I define X and Y in the same file. Moreover, if I include the declaration of X (i.e. "x.h") into "y.h", it won't crash either.
Is there a rationale for such behavior?
                        
The issue seems to be that when defining pointers-to-members after the class is declared, but before it's defined, MSVC has to guess at the class' inheritance model. There are four ways to handle this:
Use the MS-specific keyword
__single_inheritance,__multiple_inheritance, or__virtual_inheritancein the declarationclass X;in "y.h", to force it to use a specific model. Of these,__single_inheritanceis the most efficient, but only usable when the class doesn't have multiple or virtual inheritance; sinceXhas no base classes, this is fine.Use the MS-specific pragma
pointers_to_members, for the same reason. Again, we can use "single inheritance", which is the most efficient choice.Change the Pointer-to-member representation option in the IDE; I'm not sure how to do this, unfortunately, since I can't find the option.
/vmg