C++-关于临时变量的释放?
C++中临时变量的作用域是确定的么?什么时候释放?编译器有没有一种规律可循的做法?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
C++中临时变量的作用域是确定的么?什么时候释放?编译器有没有一种规律可循的做法?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(5)
如果函数没有返回值,则函数内部的变量在函数执行结束之后全部释放;
如果函数有返回值,则函数内临时变量在函数所在的赋值语句执行完毕之后释放.
可以看下面这段代码就明白了:
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
Base():selfid(++n)
{
cout<<"Base "<<selfid<<" by default"<<endl;
}
Base(const Base& other):selfid(++n)
{
cout<<"Base "<<selfid<<" by copy from "<<other.selfid<<endl;
}
Base& operator=(const Base& other)
{
cout<<"Base "<<selfid<<" by = from "<<other.selfid<<endl; return *this;
}
virtual ~Base()
{
cout<<"Base "<<selfid<<" destroyed"<<endl;
}
private:
int selfid;
static n;
};
int Base::n=0;
Base Test()
{
return Base();
}
int main()
{
Base b1;
b1=Test();
return 0;
}
运行结果如下:
#include <iostream>
using namespace std;
class X {
public:
X() : i(0) { cout << "Xn";}
X(int b) : i(b) { cout << "int constructor" << endl;}
X(const X& other) { cout << "copyn"; }
X& operator= (const X& rhs) {cout << "= assignn"; return *this; }
~X() { cout <<"~X + " << i << endl;}
private:
int i;
};
X f() {
X xx;
return xx;
}
void f(X x) {}
int main() {
X x;
cout << "==============" << endl;
x = f();
cout << "==============" << endl;
const X& cs = 3;
cout << "==============" << endl;
f(x);
cout << "==============" << endl;
// cout << "test NRV " << endl;
// X x1 = f();
return 0;
}
f(x);形参通过copy构造出来的临时变量,在函数调用完之后,超出作用域就释放了。
但是const X& cs = 3;这里
相当于:
X tem(3);
const X& cs = tem;
//这里构造出来的临时变量的生命周期是与cs一样的。main函数结束时释放。
会不会产生临时变量甚至与编译器的优化有关。
cout << "test NRV " << endl;
X x1 = f();
如果编译器有NRV(named return value)的优化。
X f() {
X xx;
//....对xx进行操作
return xx;
}
会被转化为
void f(X& _result) {
_result.X::X();
//对_result进行操作
return;
}
你会发现,没有临时变量。只调用了一次构造函数。
这里有关于构造函数的语义,以及编译器的优化。
如果没有启用的话,会有临时变量的产生,代码转化为
void f(X& _result) {
X _tem;
_tem.X::X();
//对_tem进行操作
_result.X::X(_tem);
return;
}
具体可以参考《Inside c++ Object》一书。
最小的作用域就是一个代码块,用一对大括号包围着。函数其实也算是一个种特殊的代码块。
无论是系统默认产生的临时变量,还是程序员主动创建的临时变量,一般都只在它存在的代码块中有效,出了代码块,系统就会释放临时变量了。
如果函数没有返回值,则函数内部的变量在函数执行结束之后全部释放;
如果函数有返回值,则函数内临时变量在函数所在的赋值语句执行完毕之释放.
但是有个字符串常量不同,字符串常量是存储在静态区的,在程序结束时释放。
不仅仅函数中会产生临时变量,一些表达式中也会产生临时变量~比如
printf("%dn",s + t);
这个时候临时变量的生命期是:临时变量应该在导致临时变量创建的完整表达式求值过程的最后一个步骤被析构。
上面的规则其实还有两条例外 :
string s,t;
string v = 1 ? s + t : s - t;
这里完整表达式是 ?语句, 但是在完整表达式结束以后临时变量还不能立即销毁 ,而必须在变量v赋值完成后才能销毁 ,这就是例外规则1:
凡含有表达式执行结果的临时变量 ,应该存留到对象的初始化操作完成后销毁。
string s,t;
string& v = s + t;
这里 s+t产生的临时变量即使在变量 v的赋值完成后也不能销毁 ,否则这个引用就没用了,这就是例外规则 2:
如果一个临时变量被绑定到一个引用 ,这个临时变量应该留到这个临时变量和这个引用那个先超出变量的作用域后才销毁。
推荐一份参考资料:
C++中的临时变量
讲的很详细,值得细看~