函数返回值的问题

来源:互联网 发布:ipad照片怎么导入mac 编辑:程序博客网 时间:2024/05/16 07:02

今天复习c++, 不看不知道,复习吓一跳. 又发现了我之前认识上的一些误区. 下面是我在函数返回值问题上的误区.

       我一直以为函数在返回的时候会在如果不是引用的话会在创建一个新的对象. 但是经过我今天的亲身实践发现这是不准确

这个东西要和编译器有联系.下面是我所测试时用的程序.


*********************************************  > Author:gw  > Created Time: Sat 11 Oct 2014 04:33:49 PM CST **************************************/#include<iostream>   using namespace std; class CMake{public:CMake(int n){   m_data = n ;cout << "构造 " << m_data << endl;}CMake(const CMake &obj){   m_data = obj.m_data + 1;cout << "拷贝构造" << m_data << endl;}~CMake() { cout << "析构 " << m_data << endl;} // 强制类型转换即把 该对象强制转换为其它类型的对象// 返回值类型为要强制转换的类型operator int() const { return m_data; }    public:    int m_t;private:int m_data;}; CMake MakeObject( int n ){cout<<"MakeObjectB------------"<<endl;cout<<"函数入口地址"<<&n<<endl;    CMake f1(20);    cout<<"f1->addr: "<<&f1<<endl;CMake  p (n);cout<<"p ->addr: "<<&p<<endl;cout<<"MakeObjectE------------"<<endl;return p;}int main(){        CMake a=MakeObject(8);int b=a;    //这里会隐式调用CMake类的强制类型转换函数            //存在就调用不存在就报错cout<<"b:"<<b<<endl<<"b ->addr :"<<&b<<endl;cout<<"******"<<endl;        cout<<"a ->addr: "<<&a<<endl;    return 0;}

下面是在g++编译器中测试结果:


      由于栈的空间是向低地址扩展的,很明显发现不对劲p的地址(0xbf9c0f68)居然比函数的入口地址(0xbf9cof54)大

呵呵这明显说明p所在的栈空间不是MakeObject()函数所在的栈空间. b是在main函数中创建的而p和a的地址相同

b的地址小于p的地址.  综合上面的因素 我得出一个大胆的结论: 

    g++编译器在处理函数返回值得时候会做优化, 它直接把返回值创建在调用它的函数所在的栈空间,'='左面是一个初始化操作的话,只会构造一个对象. (返回值 , "="左面对象 )这样可以省去两次调用拷贝构造函数.

       "析构8"  出现在main函数结束时,这也片面证明了这个观点.


下面是在vs2010中测试结果


这里在初始化a时 调用一次拷贝构造函数

但为什么没有析构a我目前也不知道?  算了留下点疑问等以后慢慢解决.



0 0