构造函数的使用术语是什么

What is the terminology for this use of a constructor?

本文关键字:术语 是什么 构造函数      更新时间:2023-10-16

一位同事编写了以下代码,我确信这是错误的。

我想向他解释这些问题,但不知道合适的术语,所以我找不到支持我立场的参考资料:

他的代码:

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

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

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

你能指出一些详细描述使用的参考文献/术语/页面吗?

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

(或者我的分析完全错误……如果是这样,我很想知道(


澄清:

_bstr_t是一个C++类,通常被微软用来包装他们的bstr类型,因此它有构造函数/析构函数/运算符等。

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

你说得对。

BSTRwchar_t *的typedef,而CComBSTR/_bstr_t具有到wchar_t *的非常数转换运算符。

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

你可以使用

_bstr_t someString ("Hello World");

或者甚至_bstr_t someString = "Hello, World";

有问题的代码

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

正在执行转换构造函数调用,该调用使用传递的wchar_t[]创建一个bstr_t实例。这本身就很好。例如,如果你想调用一个接受BSTR的函数,并在其中传递一个字符串文字,你可以很容易地做到这一点:

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

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

然而,有问题的代码是不好的,因为_bstr_t实例随后被用来实例化一个BSTR实例(使用类bstr_t中的转换运算符(,该实例的寿命比临时实例长(临时实例在分号处被破坏,BSTR指针someString的寿命远远超过该值(。因此,您得到了一个悬空的BSTR指针someString,使用它会导致未定义的行为。如果OLE堆选择将用于字符串的内存映射到进程地址空间中,它甚至可能看起来是有效的。

class _bstr_t随实现(Windows SDK中的文件comutil.h(一起提供,因此您可以使用调试器进入代码,并查看在创建临时时有一个SysAllocString()调用,在销毁时有一次SysFreeString()调用,后者在代码进入下一行之前发生。因此,OLE堆中的字符串对象在代码进入下一行之前被释放,并且someString指针在所讨论的代码之后立即挂起。我想这足以说服最怀疑的人。

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

 _bstr_t someString(L"Hello World");