D 错误:空解引用

D 错误:空解引用,d,D,此代码: int main(char[][] args) { MyObject obj; obj.x; return 0; } 给我:错误:当我用-O标志(在dmd2上)编译函数时,函数_Dmain中的空解引用,为什么?obj不是在堆栈上分配的吗?我应该总是使用new来创建对象吗?我不是很好地阅读你的代码,因为我是一个VB的家伙,但是看起来你在启动一个没有值的对象 创建一个名为obj的对象 你叫obj.x 然后返回“0”(零) 你到底在干什么?我非常确定obj需要是新的,并且您需要

此代码:

int main(char[][] args)
{
  MyObject obj;
  obj.x;
  return 0;
}

给我:
错误:当我用-O标志(在dmd2上)编译函数时,函数_Dmain中的空解引用
,为什么?
obj
不是在堆栈上分配的吗?我应该总是使用
new
来创建对象吗?

我不是很好地阅读你的代码,因为我是一个VB的家伙,但是看起来你在启动一个没有值的对象

创建一个名为obj的对象 你叫obj.x 然后返回“0”(零)


你到底在干什么?我非常确定obj需要是新的,并且您需要返回物理“0”以外的内容。

摘要:您必须创建新对象。总是

D类比C++更接近C语言或java。具体地说,对象总是,总是参考值

MyObject在引擎盖下是指向实际对象的指针。因此,当您使用
MyObject obj
,您正在创建一个
null
指针,实际上还没有创建对象。必须使用
new
操作符创建对象:

auto obj = new Object();
这将在堆上创建obj

您不能直接在D中的堆栈上构造对象。您最好执行以下操作:

scope obj = new MyObject;
int main(string[] args)
{
    ...
}
允许编译器将对象放在堆栈上,但不必这样做

(事实上,我怀疑这可能会在D2的未来版本中消失。)

另一方面,如果您使用的是D2,那么我相信您的主要功能应该如下所示:

scope obj = new MyObject;
int main(string[] args)
{
    ...
}

char[]
string
具有相同的物理布局,但含义略有不同;具体来说,
string
只是
不可变(char)[
的别名,因此使用
char[]
可以绕过常量系统保护。

0表示成功。这是一个UNIX的东西。如果你不给它一个默认值,D中的所有变量都会自动初始化。在引用对象的情况下,这个值是空的——这就是为什么它抱怨他试图遵从空引用的原因。所以要点仍然有效(忘记零),它需要初始化为“NEW”。是的。主要观点绝对正确。问题是变量是用null初始化的,而不是给它分配一个实际的对象(在本例中可能是用
new
)。只是在D中,它不会是一个未初始化的值。而是一个默认的初始化值。因此,您得到的是
null
,而不是垃圾。这仍然是一个错误,但它是一个定义良好的错误,无论您的平台或编译器实现如何,它都是完全确定的。。。
MyObject*obj
是指向obj的指针还是指向obj的双指针?i、 e.假设对象没有问题,我可以向其投射指针吗?@serejko
MyObject*obj
将是指向对象引用的指针,这通常是一件非常奇怪的事情。一般来说,你不应该在D中使用指针。如果你需要它们,它们就在那里,但是它们不安全,你通常不需要它们。我真的建议你更详细地阅读数字火星网站上的文档。更好的是,如果你能负担得起的话,去读安德烈·亚历山德雷斯库的新书《D编程语言》。总的来说,它解释得很好。@DK
scope
在这种情况下,我理解它肯定会被淘汰,但目前它仍然有效。我认为,现在的想法是,如果您想要具有有限生命期的用户定义类型(例如,当存在创建它们的作用域时被销毁),您应该使用结构。@Jonathan指针不一定不安全。只要您只将它们放入堆内存,不将它们强制转换为不兼容的类型,也不对它们执行未经检查的算术,它们就完全安全了。只有当你做了一些愚蠢的事情,比如逃逸堆栈内存或者用你的高度除以一个指针,坏事情才会发生。至于逐步淘汰范围,这是一个极其愚蠢的决定;我就不说了。@DK好吧,理论上,SafeD允许指针的任何用法都是安全的,而不允许其他用法,所以如果你坚持使用SafeD,它应该是很好的,并且相当清楚。例如,使用关联数组从中的
获取指针是一种安全的情况。不过,D是这样设计的,指针在C或C++中不需要任何地方,如果你不需要它们,那么最好避免它们。特别是,类已经是引用类型了,所以在类中使用指针通常是没有意义的。