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_inheritance
in the declarationclass X;
in "y.h", to force it to use a specific model. Of these,__single_inheritance
is the most efficient, but only usable when the class doesn't have multiple or virtual inheritance; sinceX
has 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