Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Object 是否在D中间接访问对象?_Object_D - Fatal编程技术网

Object 是否在D中间接访问对象?

Object 是否在D中间接访问对象?,object,d,Object,D,正如我所读到的,D中的所有对象都是完全位置独立的。如何达到这一要求 我想到的一件事是,所有引用都不是指向对象的指针,而是指向某个代理,所以当您移动对象(在内存中)时,您只需更新该代理,而不是程序中使用的所有引用 但这只是我的猜测。它是如何在D中实现的?编辑:底线在前面,没有代理对象,对象直接通过常规指针引用/编辑 结构不允许保留指向自身的指针,因此如果它们被复制,它们应该继续工作。但该语言并未严格执行这一点: struct S { S* lol; void beBad() {

正如我所读到的,D中的所有对象都是完全位置独立的。如何达到这一要求

我想到的一件事是,所有引用都不是指向对象的指针,而是指向某个代理,所以当您移动对象(在内存中)时,您只需更新该代理,而不是程序中使用的所有引用


但这只是我的猜测。它是如何在D中实现的?

编辑:底线在前面,没有代理对象,对象直接通过常规指针引用/编辑

结构不允许保留指向自身的指针,因此如果它们被复制,它们应该继续工作。但该语言并未严格执行这一点:

struct S {
    S* lol;
    void beBad() {
        lol = &this; // this compiler will allow this....
    }
}

S pain() {
    S s;
    s.beBad();
    return s;
}

void main() {
    S s;
    s = pain();
    assert(s.lol !is &s); // but it will also move the object without notice!
}
(编辑:事实上,我想你可以使用postblit来更新内部指针,所以这并不是没有通知的。如果你足够小心,你可以让它工作,但是同样,如果你足够小心,你也可以在脚趾之间射击,而不会撞到你的脚。编辑2:事实上,不,编译器/运行时仍然可以移动它,甚至不需要调用postblit。发生这种情况的一个例子是,它将堆栈帧复制到堆中以进行闭包。结构数据在没有通知的情况下被移动到新地址。所以是的。/edit)

实际上,断言不能保证通过,编译器可能会选择直接对
main
中声明的本地对象调用
pain
,这样指针就可以工作了(虽然我无法在演示中强制执行此优化,但通常情况下,当您从函数返回结构时,它实际上是通过调用方传递的隐藏指针完成的-调用方说“将返回值放在此处”,从而在某些情况下避免复制/移动)

但无论如何,关键是编译器可以随意复制或不复制一个结构,所以如果你把它的地址保留在里面,它可能会在没有通知的情况下变得无效;保留指针不是编译错误,而是未定义的行为

类的情况不同。允许类在内部保留对
的引用,因为类(理论上,由垃圾收集器实现)是一个具有无限生存期的独立对象。而它可能会被移动(例如,是一个移动的GC(今天没有在D中实现)),如果它被移动,所有对它的引用,无论是内部的还是外部的,都需要更新

所以类不能像structs那样从下面取出内存(除非程序员自己动手,绕过GC…)


与位置无关的事情我很确定,就是只引用结构,并且只引用规则,它们不能有指向自身的指针。引用或指针没有神奇的作用——它们确实可以使用内存地址,没有代理对象。

Hmm,也许我给你上下文,我正在阅读A.Alexandrescu,以及移动对象的能力freely对我来说意味着,移动后所有的东西都像原来一样坚固。如果D使用原始指针,我不知道如何实现这一点,因为移动后整个对象都在另一个地址。他只写了禁止内部指针的内容(我看不出有什么理由,但这是另一个故事).所以我可以有外部指针。它的页码是多少?我有一本书的副本,想看看上下文。但我很确定它不会真正影响外部指针,因为它们都是有风险的(例如,一个指向局部变量的指针就可以了,只要局部变量仍然在作用域中——之后,它就错了,因为变量已经不存在了),或者由内存分配器很好地定义(指向
malloc
'd结构的指针保证在对象
空闲之前一直有效,而指向GC'd对象的指针保证始终有效。)p、 249,底部第二段。我误用了
指针
——有一个
您使用对给定类型实例的引用,因此
a=new MyClass…
意味着问题(IMHO)如果你想移动这个实例占用的内存,
a
在移动后如何知道这个实例在哪里?我几乎可以肯定这一部分只适用于结构,但为了证实这一点,我问了D论坛:虽然如果一个类被移动了,我很确定GC有责任扫描所有内存,寻找指向它的指针也要注明日期(这是它目前无法做到的,它无法准确地知道局部变量的位置)哦,我的天!你说得很对,这整个部分只涉及结构。因此postblit构造函数首先是结构的专业。现在,一切都有完美的意义,因为它是你可以随意重新分配的值类型。非常感谢你的帮助Adam!