2014-07-03 63 views
5

一位同事写下了下面的代码,我相信这是错误的。这是用于构造函数的术语是什么?

我想解释的问题给他,但不知道适当的期限,所以我找不到引用支持我的立场:

他的代码:

BSTR someString = _bstr_t(L"Hello World"); 

为什么我认为这是错误的:
我认为_bstr_t(L"Hello World");调用_bstr_t的构造函数,并创建该类型的短暂的临时变量。该临时文件将被自动删除,并且在该行代码之后(在分号顺序点之后)立即释放该文件的字符串空间。
这将使someString指向已释放的内存。

问题:
构造函数调用的正确名词是什么?

你能指出一些引用/术语/页面来详细描述使用吗?

是否有临时_bstr_t对象的术语?
我想我会称它为“匿名,临时变量”,但我不知道这在技术上是否准确。

也许我在我的分析完全错误....如果是的话,我很想知道


对于澄清:

_bstr_t is a C++ class,一般由微软用来包装它们的BSTR类型,所以它具有构造/拆解/操作等等。

BSTR是一种typedef只是WCHAR*,所以它没有任何逻辑。它只是一个愚蠢的指针。

回答

3

中的代码问题

BSTR someString = _bstr_t(L"Hello World"); 

正在做一个conversion constructor call它可以创建通过wchar_t[]一个bstr_t实例。这本身就很好。例如,如果你想调用一个函数接受BSTR并传递一个字符串在那里,你可以很容易地做到这一点:

someFunction(_bstr_t(L"Hello World")); // OKAY 

,这将是可以的,因为临时将生存直到整个语句结束它结束于分号所在的位置(这就是C++临时对象的工作方式)。

但是所讨论的代码是不行的,因为_bstr_t实例随后被用于实例化一个BSTR实例,它比临时(临时设置在分号和BSTR破坏居住更长(在bstr_t类使用转换运算符)指针someString的生活远远超出了这一点)。所以你得到一个悬挂BSTR指针someString使用它导致未定义的行为。如果OLE堆选择保留用于映射到进程地址空间的字符串的内存,它甚至可能会工作。

class _bstr_t与实现(在Windows SDK文件comutil.h)提供的,所以你可以进入你的调试器的代码,并看到有当临时创建一个SysAllocString()呼叫,然后一个SysFreeString()呼叫时被销毁而后者在代码进入下一行之前发生。因此,在代码进入下一行之前,OLE堆中的字符串对象会被释放,并且指针在相关代码之后立即悬空。我想这足以说服即使是最怀疑的人。

所以是的,你是对的,代码是错误的。正确的代码是:

_bstr_t someString(L"Hello World"); 
+0

谢谢,术语*“转换构造函数”*是我正在寻找。 – abelenky

5

你说得对。

A BSTRwchar_t *的typedef,并且CComBSTR/_bstr_t具有非const转换运算符到wchar_t *

因此,分配了一个临时的_bstr_t,通过转换运算符将一个指向其开始的指针指定给someString,并且在超出范围时释放该对象。然后你得到一个悬挂指针。

您可以使用

_bstr_t someString ("Hello World"); 

代替,甚至_bstr_t someString = "Hello, World";

+0

很高兴你同意。我的问题是“范围”。我通常认为一个对象的范围是括号到括号;从'{'直到匹配的'}'。但是这里没有括号......那么究竟是什么定义了临时的'_bstr_t'的“范围”? – abelenky

+1

@abelenky:相关:http://stackoverflow.com/questions/3041959/life-scope-of-temporary-variable –

相关问题