C# C中的安全,不是C++,指针/引用的简单返回
C++代码:C# C中的安全,不是C++,指针/引用的简单返回,c#,c++,pointers,reference,dangling-pointer,C#,C++,Pointers,Reference,Dangling Pointer,C++代码: person* NewPerson(void) { person p; /* ... */ return &p; //return pointer to person. } C代码: person NewPerson() { return new person(); //return reference to person. } 如果我理解这个,C++中的例子就不行了,因为P会 如果超出范围,则函数将返回一个挂起指针的野生指针 C中的示例是可以的,因为只
person* NewPerson(void)
{
person p;
/* ... */
return &p; //return pointer to person.
}
C代码:
person NewPerson()
{
return new person(); //return reference to person.
}
如果我理解这个,C++中的例子就不行了,因为P会 如果超出范围,则函数将返回一个挂起指针的野生指针
C中的示例是可以的,因为只要有对它的引用,匿名新人就会留在范围内。调用函数得到一个在C++中,P’会在堆栈上生存,当函数返回时会被阻塞。在C语言中,垃圾收集器知道在最后一个引用丢失之前不会对其进行阻塞
“clobber”在这里被随意使用…:p本例中的作用域规则类似,但在C中,如果将返回值分配给某个对象,则只要该对象包含对其的引用,就不会对其进行垃圾收集。如果未将其分配给某个对象,则没有任何对象包含对其的引用,并且在收集器下次执行时将对其进行垃圾收集
person* NewPerson(void)
{
person p();
/* ... */
return &p; //return pointer to person.
}
p不是一个人,看。因此,您将得到一个编译器错误
剩下的,是的,你是对的
我做对了吗
对
:在C++人P中;声明函数,并且不会调用person的默认构造函数。只需写个人p在C++中,这将不起作用,因为返回一个临时引用,一旦函数结束,将被破坏。您需要在堆上创建一个新人,然后返回对此人的引用。
是的,您做对了 但是,在C++中,你会真正喜欢这个< /P>person NewPerson()
{
person p;
/* ... */
return p; //return person.
}
在一个电话里一定要
person x = NewPerson();
编译器将优化返回值的复制
C++中的示例不正确,因为“p”将超出范围,函数将返回无效指针。
对 C中的例子是可以的,因为只要有任何引用,匿名的“新人”就会留在范围内 这或多或少是正确的,但你的术语并不完全正确。C中的作用域是可以使用非限定名称的文本区域。此处的对象没有名称。生存期是保证存储位置有效的运行期。范围和寿命是相互关联的;当控件将代码与作用域关联时,通常允许在该作用域内声明的局部变量的生存期结束。然而,在某些情况下,局部变量的生命周期比控制在其作用域内的时间更长或更短另外,请注意,使其保持活动状态的不是对Person对象的任何引用。引用必须是根。您可以有两个相互引用但在其他方面无法访问的Person对象;每个人都有一个引用的事实并不能让他们活着;其中一个引用必须是根引用。您可能是根引用,但它们都是果实:除了用人P而不是人P—P的错误不是C++语言中的临时对象。抱歉你是正确的-我现在觉得自己投票了:Oyy:我不理解笨拙:我应该更技术化:我的意思是它不再以一种有效的方式存在。直到它被写过,对象仍然存在于它所在的地方,但是一旦变量超出C++版本的范围,就没有保证,而且它实际上变得非常非常可能,对象很快就会被重写。好的,但是它不会在速度上被修改,对吧?因为指针的返回速度更快?或者,这可能是C++中的一个很好的选择,在这个特殊的情况下,使分解功能能够使编译器省略返回值的复制,并在X中构造它。大多数编译器都利用了这一点。好吧,那么它的速度也会一样,就好像你返回了一个指向一个新人的指针?