无论何时运行以下程序,它都会因这种奇怪的异常而崩溃:
“ dfun.exe中的0x00B31028引发了异常:0xC0000005:访问冲突读取位置0x00000000。”
我正在Visual Studio中使用visuald和dmd进行编译。不确定是否要提供更多信息,请问...
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;
}
但是如果将代码更改为此,则具有相同的基本功能:
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;
}
效果很好。 班上休息什么?
答案 0 :(得分:4)
您没有在以下行上初始化事件:
Event!(int, char) doIt;
doIt.addHandler(&foo);
类是引用类型,并且以null
作为其初始值(.init
)。这意味着您将需要明确初始化doIt
:
Event!(int, char) doIt = new Event!(int, char)();
可以使用auto
将其缩短一点:
auto doIt = new Event!(int, char);
那应该解决这个问题。这里的一个问题:Event
是否需要成为一个类并具有引用语义,或者结构是否同样可以满足您的目的?如果可以使用结构,则无需对其进行初始化。
您的addHandler function
中还有另外一个细小的nitpick:无需进行++length; arr[$-1]
跳舞-D有concatenation operator ~:
public void addHandler(void function(Args) handler)
{
_funcArray ~= handler;
}