Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.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
C++ 临时对象、函数参数和隐式转换_C++ - Fatal编程技术网

C++ 临时对象、函数参数和隐式转换

C++ 临时对象、函数参数和隐式转换,c++,C++,在以下场景中: struct Foo { // ... operator Bar() {... } // implicit cast to Bar } Foo GetFoo() { ... } void CallMeBar(Bar x) { ... } // ... CallMeBar( GetFoo() ); [edit]修复了演员操作符d'oh[/edit] GetFoo返回Foo类型的临时对象。这个对象在CallMe返回之前是否仍然存在?标准怎么说 我知道如果CallM

在以下场景中:

struct Foo
{
   // ...
   operator Bar() {... }  // implicit cast to Bar
}

Foo GetFoo() { ... }
void CallMeBar(Bar x) { ... }

// ...
CallMeBar( GetFoo() );
[edit]修复了演员操作符d'oh[/edit]

GetFoo
返回Foo类型的临时对象。这个对象在CallMe返回之前是否仍然存在?标准怎么说

我知道如果
CallMe
接受Foo,临时对象在
CallMe
返回之前不会被销毁。但是,我不确定隐式强制转换是否会改变这一点,并且只有临时的
能够保证生存



典型的情况是Foo=CString,Bar=char*,即Bar引用Foo持有(并释放)的数据

只要您按值返回它们,它们就会一直存在,直到CallMeBar完成

不过,你的演员操作员有点不对劲。应该是:

struct Foo
{
   // ...
  operator Bar() {... }  // implicit cast to Bar
}

>如

> P>不管抛出,临时对象将“幸存”调用C++的代码> Calm()/Cuth>函数,因为C++标准:

12.2.3[…]临时对象被销毁,作为评估完整表达式(1.9)的最后一步,完整表达式(1.9)包含创建临时对象的点(词汇)。[……]


1.9.12完整表达式是一个表达式,它不是另一个表达式的子表达式。

我倾向于这样认为-神奇的字符是分号。分号触发析构函数。

< p>它将存活,但依赖于此事实可能会混淆,并且可能导致代码的客户端达到C++标准,询问堆栈溢出等问题;例如,当有人这样做时会发生什么:

Bar b = GetFoo();
CallMeBar(b);
这一次,Foo在调用CallMeBar之前就已经出现了,但是大多数程序员希望通过转换来创建一个独立的对象,因此代码的行为与:

CallMeBar(GetFoo());
这就是为什么
std::string
没有对
char*
的隐式转换,这与
CString
LPCTSTR
的转换不同。相反,
std::string
具有
c_str()
成员函数,该函数具有相同的约束条件,但在调用代码时更明显的是,它不是真正的转换:

CallMePtr(GetString().c_str());   // OK

char* p = GetString().c_str();    // Bad
CallMePtr(p);                     // Badness manifests

const string &s = GetString();    // use "the most important const"
CallMePtr(s.c_str());             // Best be on the safe side

这里所有的东西都是按价值计算的,这是有意的还是涉及到了一些参考资料?第一个例子实际上还可以,不是吗?GetFoo()返回一个Foo,该Foo转换为一个条,并复制到变量b中。然后它从此过着幸福的生活:)好吧,如果演员是一个适当的转换,当然。但是如果CallMeBar依赖于仍然存在的Foo,这就是OP所询问的,那么就有问题了。如果从Foo到Bar的强制转换意味着生成的Bar只在Foo有效时才有效,那么我假设副本也是如此。我们基于的模型是从CString到LPCTSTR的演员阵容,我碰巧认为这是个坏主意。它不是一个真正的转换,它是对CString内部组件的访问器。啊,我明白了。我一直将Bar解释为一种完整的值类型,但发布的代码并不真正支持这种假设。别介意我:)