关于垃圾收集的问题在vc ++ 2005中 [英] Question about garbage collection in in vc++ 2005

查看:65
本文介绍了关于垃圾收集的问题在vc ++ 2005中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读ppt( http:// www .gotdotnet.com / team / pdc / 4064 / tls310.ppt

来自aross这句话。


"用户可以利用析构函数。 C ++编译器自动生成所有Dispose

代码,包括链接对Dispose的调用。 (没有

处理模式)"


但是Dispose可以抛出异常。被禁止的例外吗?

I was reading a ppt ( http://www.gotdotnet.com/team/pdc/4064/tls310.ppt )
and came aross this statement.

"Users can leverage a destructor. The C++ compiler generates all the Dispose
code automatically, including chaining calls to Dispose. (There is no
Dispose pattern)"

but Dispose can thrown an exception. Is the exception supressed?

推荐答案

Hasani(从地址中删除nospam)写道:
Hasani (remove nospam from address) wrote:
我正在阅读ppt(< a rel =nofollowhref =http://www.gotdotnet.com/team/pdc/4064/tls310.ppttarget =_ blank> http://www.gotdotnet.com/team/pdc/4064 /tls310.ppt )
并提出了这个声明。

用户可以利用析构函数。 C ++编译器自动生成所有的
Dispose代码,包括将调用链接到Dispose。 (有
没有Dispose模式)

但是Dispose可以抛出异常。是否存在异常?
I was reading a ppt ( http://www.gotdotnet.com/team/pdc/4064/tls310.ppt )
and came aross this statement.

"Users can leverage a destructor. The C++ compiler generates all the
Dispose code automatically, including chaining calls to Dispose. (There
is no Dispose pattern)"

but Dispose can thrown an exception. Is the exception supressed?




析构函数也可以抛出异常。他们没有受到压制。由于

破坏是确定性的,大多数时候你可以自己处理异常

。当析构函数抛出异常而另一个

异常正在展开堆栈时,异常会链接在一起。


当然,建议你不要从析构函数中抛出异常。

(如果你用其他语言编写Dispose也是如此。)


-

Brandon Bray,Visual C ++编译器 http://blogs.msdn.com/branbray/

此帖子按原样提供,不提供任何保证,也不授予任何权利。



Destructors can throw exceptions too. They are not suppressed. Since
destruction is deterministic, most of the time you can handle the exception
yourself. When an exception is thrown from a destructor while another
exception is unwinding the stack, the exceptions are linked together.

Of course, it is recommended that you not throw exceptions from destructors.
(The same is true if you are writing Dispose in other languages.)

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
This posting is provided AS IS with no warranties, and confers no rights.


我只是想确保我是这是正确的。

在c ++。net的下一个版本中,让我们假设以下代码


============ ===================

#using< mscorlib.dll>


使用命名空间系统;

使用命名空间System :: Net :: Sockets;


public __gc class Foo:public IDisposable

{

public:

Foo()

{

_socket = new

System :: Net :: Sockets :: Socket(AddressFamily :: InterN etwork,

SocketType :: Stream,ProtocolType :: Tcp);

_isocket = dynamic_cast< IDisposable *>(套接字);

}


无效IDisposable :: Dispose()

{

_isocket-> Dispose();

}


~Foo()

{

试试

{

Dispose();

}

catch(...)

{

}

}


__property套接字* get_Socket()

{

// TODO:检查以确保物品不被丢弃。

返回_socket;

}


私有:

System :: Net :: Socket __gc * _socket;

IDisposable __gc * _isocket;

};


int main(int argc,char * argcv [])

{

{

Foo f;

对象__gc * socket = f.Socket;

}

//现在应该调用析构函数。

返回0;

}


==== ======================

我假设幕后发生以下情况。


1)f.Dispose()将在

中的相同线程上下文中自动调用,其中f已初始化且未执行异常处理

如果f.dtor()抛出异常。

2)f.dtor()[与1相同的文本]

3)没有执行激活处理时f.Dispose()和

f.dtor()会自动调用。

4)当私有变量f._socket不会立即完成时

变量f超出范围。它将在下次由系统执行垃圾收集时完成,或者调用GC :: Collect。

5)当我自动说,这是在编译时完成而不是运行时。

编译器添加代码来执行1,2和3. 4将在运行时。


提前Thx,我只是想深入了解c ++。net的这个新的

功能。


另外,如果一个对象包含一个终结器,例如作为Regex类。在

下一个版本的c ++中,终结器将被视为析构函数,因此我可以做到


正则表达式__gc *正则表达式=新的正则表达式();

删除正则表达式;


" Brandon Bray [MSFT]" <峰; br ****** @ online.microsoft.com>写在消息

新闻:u6 ************* @ TK2MSFTNGP12.phx.gbl ...
I just want to make sure I''m getting this right.
In the next release of c++.net, lets assume the following code

===============================

#using <mscorlib.dll>

using namespace System;
using namespace System::Net::Sockets;

public __gc class Foo : public IDisposable
{
public:
Foo()
{
_socket = new
System::Net::Sockets::Socket(AddressFamily::InterN etwork,
SocketType::Stream, ProtocolType::Tcp);
_isocket = dynamic_cast<IDisposable*>(socket);
}

void IDisposable::Dispose()
{
_isocket->Dispose();
}

~Foo()
{
try
{
Dispose();
}
catch(...)
{
}
}

__property Socket* get_Socket()
{
//TODO: do check to make sure object is not disposed.
return _socket;
}

private:
System::Net::Socket __gc* _socket;
IDisposable __gc* _isocket;
};

int main(int argc, char* argcv[])
{
{
Foo f;
Object __gc* socket = f.Socket;
}
//the desctructor should have been called by now.
return 0;
}

==========================

I''m assuming the the following happen behind the scenes.

1) f.Dispose() will be called automatically in the same thread context in
which f was initialized and no exception handling being performed
if f.dtor() throws an exception.
2) f.dtor() [same text as 1]
3) there is no excpetion handling performed when f.Dispose() and the
f.dtor() is automatically called.
4) the private variable f._socket will not be finalized instantly when
variable, f, goes out of scope. It will be finalized the next time garbage
collection is performed by either the system, or a call to GC::Collect.
5) When I say automatically, this is done at compile time and not runtime.
the compiler adds code to do 1, 2 and 3. 4 would be at runtime.

Thx in advance, I''m just trying to get a solid understanding of this new
feature of c++.net.

Also, if an object contains a finalizer, such as the Regex class. In the
next version of c++, will finalizers be treated as destructors so I can do

Regex __gc* regex = new Regex();
delete regex;

"Brandon Bray [MSFT]" <br******@online.microsoft.com> wrote in message
news:u6*************@TK2MSFTNGP12.phx.gbl...
Hasani(从地址中删除nospam) )写道:
Hasani (remove nospam from address) wrote:
我正在读一个ppt(
http://www.gotdotnet.com/team/pdc/4064/tls310.ppt )并发表了此声明。

用户可以利用析构函数。 C ++编译器自动生成所有的
Dispose代码,包括将调用链接到Dispose。 (有
没有Dispose模式)

但是Dispose可以抛出异常。是否存在异常?
析构函数也可以抛出异常。他们没有受到压制。由于破坏是确定性的,大多数时候你可以自己处理
I was reading a ppt ( http://www.gotdotnet.com/team/pdc/4064/tls310.ppt ) and came aross this statement.

"Users can leverage a destructor. The C++ compiler generates all the
Dispose code automatically, including chaining calls to Dispose. (There
is no Dispose pattern)"

but Dispose can thrown an exception. Is the exception supressed?
Destructors can throw exceptions too. They are not suppressed. Since
destruction is deterministic, most of the time you can handle the



异常。当析构函数抛出异常而另一个
异常展开堆栈时,异常会链接在一起。

当然,建议您不要从
抛出异常析构函数。 (如果你用其他语言编写Dispose也是如此。)

-
Brandon Bray,Visual C ++编译器 http://blogs.msdn.com/branbray/
此帖子按原样提供,不提供任何保证,也不授予任何权利。


exception yourself. When an exception is thrown from a destructor while another
exception is unwinding the stack, the exceptions are linked together.

Of course, it is recommended that you not throw exceptions from destructors. (The same is true if you are writing Dispose in other languages.)

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
This posting is provided AS IS with no warranties, and confers no rights.



Hasani(从地址中删除nospam)写道:
Hasani (remove nospam from address) wrote:
我假设后面发生了以下情况场景。


首先请注意,在旧语法中,确定性清理不可用。

这是新语法的一个特性。我会用旧语法回答你的问题,并单独调出有关新的

语法的任何有趣内容。


另外,请注意在旧语法中〜类映射到类的终结器

(即使它生成__dtor方法)。在新语法中,~Class将

映射到Dispose(这是析构函数),并且!Class映射到终结器。

1)f.Dispose()将是在初始化f的同一线程上下文中自动调用,如果
f.dtor()抛出异常,则不执行异常处理。


请注意,F(作为引用类)无法在旧的语法中在堆栈中实例化。因此,如果它是使用__gc指针创建的,旧的语法

仍然允许从终结器线程调用F :: Dispose(

不同于线程f是在...创建的。


新语法允许在堆栈上创建F,在这种情况下它的

析构函数(即Dispose)将即使发生

异常,也会在范围的末尾调用。因此,终结器永远不会运行。

2)f.dtor()[与1相同的文本]


在旧语法中,如果Dispose不是跑,终结者会。如果Dispose是
运行,那么终结器很可能不会。


在新语法中,C ++生成的析构函数会抑制终结。

3)当自动调用f.Dispose()和
f.dtor()时,没有执行激活处理。


这个问题没有意义。也许你问,在存在

异常的情况下,Dispose和dtor会被调用吗?


如果这是问题,答案是否定的(答案是否定的)他们两个都不能被称为b $ b。根据您在旧语法中尝试/ __ finally块的内容,

可以运行Dispose。如果是这样,终结者可能不会。如果Dispose

没有运行,终结器将运行。


在新语法中,如果类型在堆栈上分配,那么它将如果发生异常,则调用析构函数(即Dispose)



4)当变量为f时,私有变量f._socket不会立即终止。 ,超出范围。它将在下次由系统执行垃圾收集或调用GC :: Collect时完成。


这是正确的。如果析构函数没有清理Socket(即调用

Socket'的析构函数),Socket将被最终确定。

5)当我自动说,这个在编译时完成,而不是运行时。
编译器添加代码来执行1,2和3. 4将在运行时。


是的,编译器以新语法完成上述所有操作。如果您使用的是

旧语法,则不会这样做。

此外,如果对象包含终结器,例如Regex类。在c ++的下一个版本中,终结器将被视为析构函数,因此我可以
I''m assuming the the following happen behind the scenes.
First note that in the old syntax, deterministic cleanup is not available.
That is a feature of the new syntax. I''ll answer your questions in terms of
the old syntax, and separately call out anything interesting about the new
syntax.

Also, note that in the old syntax ~Class maps to the finalizer of the class
(even though it generates a __dtor method). In the new syntax, ~Class maps
to Dispose (which is the destructor), and !Class maps to the finalizer.
1) f.Dispose() will be called automatically in the same thread context in
which f was initialized and no exception handling being performed if
f.dtor() throws an exception.
Note that F (being a reference class) cannot be instantiated on the stack in
the old syntax. So, if it were created with a __gc pointer, the old syntax
would still allow F::Dispose to be called from the finalizer thread (which
is different than the thread f was created on).

The new syntax does allow F to be created on the stack, in which case its
destructor (i.e. Dispose) will be called at the end of the scope even if an
exception takes place. Thus, the finalizer should never run.
2) f.dtor() [same text as 1]
In the old syntax, if Dispose is not run, the finalizer will. If Dispose is
run, it is very likely that the finalizer will not.

In the new syntax, the C++ generated destructor suppresses finalization.
3) there is no excpetion handling performed when f.Dispose() and the
f.dtor() is automatically called.
The question doesn''t make sense. Perhaps you are asking, in the presence of
an exception, does Dispose and dtor get called?

If that is the question, the answer is no (both of the them cannot be
called). Depending on what try/__finally blocks you have in the old syntax,
the Dispose may run. If it does, the finalizer probably will not. If Dispose
doesn''t run, the finalizer will run.

In the new syntax, if the type is allocated on the stack, then it will have
its destructor (i.e. Dispose) called if an exception occurs.
4) the private variable f._socket will not be finalized instantly when
variable, f, goes out of scope. It will be finalized the next time garbage
collection is performed by either the system, or a call to GC::Collect.
That is correct. If the destructor does not clean up the Socket (i.e. call
the Socket''s destructor), the Socket will be finalized.
5) When I say automatically, this is done at compile time and not runtime.
the compiler adds code to do 1, 2 and 3. 4 would be at runtime.
Yes, the compiler does all of the above in new syntax. If you are using the
old syntax, it does not do this.
Also, if an object contains a finalizer, such as the Regex class. In the
next version of c++, will finalizers be treated as destructors so I can do




No.终结器和析构器是两个不同的东西。当没有调用析构函数时,终结器会被调用

。我们将析构函数映射到IDisposable的Dispose

方法。因此,如果您在任何ref类中定义析构函数,

C ++将为您生成Dispose模式。它也像往常一样链接

析构函数。因此,在对象上使用delete关键字将最终导致调用Dispose方法。


因为C ++编译器为您生成Dispose,所以不能写处理

你自己。相反,你需要使用析构函数语法。


希望有所帮助!


-

Brandon Bray, Visual C ++编译器 http://blogs.msdn.com/branbray/

此帖子按原样提供,不提供任何保证,也不授予任何权利。



No. Finalizers and destructors are two different things. A finalizer gets
called when a destructor was not called. We map destructors to the Dispose
method from IDisposable. So, if you define a destructor in any ref class,
C++ will generate the Dispose pattern for you. It will also chain
destructors as usual. So, using the delete keyword on an object will
ultimately cause the Dispose method to be called.

Because the C++ compiler generates Dispose for you, you cannot write Dispose
yourself. Instead, you need to use destructor syntax.

Hope that helps!

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
This posting is provided AS IS with no warranties, and confers no rights.


这篇关于关于垃圾收集的问题在vc ++ 2005中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆