Whenever the following program is ran, it crashes with this strange exception:
"Exception thrown at 0x00B31028 in dfun.exe: 0xC0000005: Access violation reading location 0x00000000."
I'm compiling in visual studio with visuald and dmd. Not sure of any more information to give, ask away...
module dfun;
import std.stdio;
class Event(Args...)
{
private void function(Args)[] _funcArray;
public this()
{
}
public void addHandler(void function(Args) handler)
{
_funcArray.length++;
_funcArray[$ - 1] = handler;
}
public void opCall(Args args)
{
foreach(func; _funcArray)
{
func(args);
}
}
}
void foo(int a, char c)
{
writeln(a, c);
}
int main()
{
Event!(int, char) doIt;
doIt.addHandler(&foo);
doIt(5, 'a');
readln();
return 0;
}
But if the code is changed to this, with the same basic functionality:
module dfun;
import std.stdio;
void foo(int a, char c)
{
writeln(a, c);
}
int main()
{
//Event!(int, char) doIt;
//doIt.addHandler(&foo);
void function(int, char)[] func;
func.length++;
func[0] = &foo;
func[0](5, 'a');
readln();
return 0;
}
It works just fine. What does the class break?
You're not initializing the event on these lines:
Event!(int, char) doIt;
doIt.addHandler(&foo);
Classes are reference types, and have null
as their initial value (.init
). This means that you will need to initialize doIt
explicitly:
Event!(int, char) doIt = new Event!(int, char)();
This can be made slightly shorter using auto
:
auto doIt = new Event!(int, char);
That should take care of that problem. One question here: does Event
need to be a class and have reference semantics, or would a struct work just as well for your purposes? If you could use a struct, there'd be no need to initialize it.
Another tiny nitpick is in your addHandler function
: there's no need for the ++length; arr[$-1]
dance - D has the concatenation operator ~:
public void addHandler(void function(Args) handler)
{
_funcArray ~= handler;
}