读书人

使用临时对象作为拷贝构造函数参数的有

发布时间: 2014-01-19 01:28:51 作者: rapoo

使用临时对象作为拷贝构造函数参数的问题
最近在看书遇到临时对象与const&的问题,以前一直没怎么注意这个细节,所以写了下面的程序作为测试

#include <iostream>

using std::cout;
using std::endl;

class A {
public:
explicit A():id(++num) {
cout<<"call A():"<<id<<endl;
}
A(const A& a):id(++num) {
cout<<"call A(const A&):"<<id<<endl;
}
~A(){
cout<<"call ~A():"<<id<<endl;
}
A& operator= (const A& a) {
cout<<"operator="<<endl;
cout<<"lvalue = A:"<<id<<endl;
cout<<"rvalue = A:"<<a.id<<endl;
return *this;
}
unsigned int id;
private:
static unsigned int num;

};

unsigned int A::num = 0;

A func1() {
cout<<"in func1()"<<endl;
A a;
cout<<a.id<<endl;
cout<<"out func1()"<<endl;
return a;
}

int main() {
A a4((A()));//语句①
cout<<"a4.id = "<<a4.id<<endl;
return 0;
}

预测的结果为
call A():1
call A(const A&):2
a4.id = 2
call ~A():2
call ~A():1

但是使用GCC 4.7和VS2008进行编译,运行结果如下
call A():1
a4.id = 1
call ~A():1


如果将语句①以换成
A a4(func1())

预测的结果为
in func1()
call A():1
1
out func1()
call A(const A&):2
call ~A():1
a4.id = 2
call ~A():2

但是使用GCC 4.7的编译运行结果如下
in func1()
call A():1
1
out func1()
a4.id = 1
call ~A():1

VS2008的结果倒是符合预测

请问这是什么原因?编译器的优化问题?

另外将拷贝构造函数的const去掉后,GCC 4.7会编译错误,这符合预测。但是VS2008却没有出错,这是因为VS2008不符合标准吗?

[解决办法]
引用:
Quote: 引用:

1. A a4((A())); A a4(func1());
GCC应该是做了优化。

2. 另外将拷贝构造函数的const去掉后,GCC 4.7会编译错误,这符合预测。但是VS2008却没有出错,这是因为VS2008不符合标准吗?
看来VS2008对标准的支持还是不够好。LZ用VS2013试一下吧。

VS2013也一样……

这居然是VC的扩展。
http://stackoverflow.com/questions/16380966/non-const-reference-bound-to-temporary-visual-studio-bug
[解决办法]
引用:
Quote: 引用:

1. A a4((A())); A a4(func1());
GCC应该是做了优化。

2. 另外将拷贝构造函数的const去掉后,GCC 4.7会编译错误,这符合预测。但是VS2008却没有出错,这是因为VS2008不符合标准吗?
看来VS2008对标准的支持还是不够好。LZ用VS2013试一下吧。

VS2013也一样……


1. 2013release版同gcc有优化, 而debug确实没有优化。
2. 为何可以绑定临时变量到non-const refercene?
这是vc的非标准扩展,把warning level改称W4,会有一个警告:
warning C4239: nonstandard extension used : 'initializing' : conversion from 'xxx' to 'xxx &'

读书人网 >C++

热点推荐