首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

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

2014-01-19 
使用临时对象作为拷贝构造函数参数的问题最近在看书遇到临时对象与const&的问题,以前一直没怎么注意这个细

使用临时对象作为拷贝构造函数参数的问题
最近在看书遇到临时对象与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 &'

热点排行