C++返回值为对象时复制构造函数不执行怎么办

来源:互联网 发布:js判断json是否存在 编辑:程序博客网 时间:2024/04/30 07:48

 先说点背景知识,调用拷贝构造函数的三种情况:

  1.当用类一个对象去初始化另一个对象时。

  2.如果函数形参是类对象。

  3.如果函数返回值是类对象,函数执行完成返回调用时。

  在辅导学生上机时,有同学第3点提出异议。有教材上的例题为证:

     

#include<iostream>
using namespace std;
class Coord
{
public:
    Coord(int a=0,int b=0);
    Coord(const Coord &p);
    ~Coord()
    {
        cout<<"using destructing..."<<endl;
    }
    void print()
    {
        cout<<x<<"   "<<y<<endl;
    }
    int getx()
    {
        return x;
    }
    int gety()
    {
        return y;
    }
private:
    int x;
    int y;
};
Coord::Coord(int a,int b)
{
    x=a;
    y=b;
    cout<<"using constructing..."<<endl;
}
Coord::Coord(const Coord &p)
{
    x=p.x;
    y=p.y;
    cout<<"using copy constructing..."<<endl;
}
Coord fun(Coord p)
{
    cout<<"--fun--"<<endl;
    int a,b;
    a=p.getx()+10;
    b=p.gety()+20;
    Coord r(a,b);
    return r;
}
int main()
{
    Coord p1(30,40);
    Coord p2;
    Coord p3(p1);
    p2=fun(p3);
    p2.print();
    return 0;
}

显示的是


显然,拷贝构造函数没有被执行。

  确定问题后,我知道道理是对的,看过的几本书,厚的、薄的,都是这么写的。会不会是编译器的差别?CodeBlocks用的是gcc。gcc开源,跟标准的变化跟得紧,莫不是第3种情况已经成了老黄历,而各种书来不及变?

  我让她到VC++6.0中运行。一会儿她的反馈,在VC++6.0中复制构造函数执行了。

  真相明白了。

  这个问题需要有个交待。

  回家后再翻各种书,无果。网络搜索,CSDN上有个贴子《函数返回值是对象,是调用了拷贝构造函数?》,其中大家给的结论,是gcc做了优化,返回值为对象时,不再产生临时对象,因而不再调用复制构造函数。

  看来不是标准发生变化。

  那如果一定想要让这个构造函数执行呢?只需让忽略gcc不要搞这个优化就行了。贴子中给了个线索,在新浪博客《命名返回值优化》。文章称通过搜索知道“这是一个称为命名返回值优化的问题,而且g++的这个编译优化竟然没有直接的关闭方法给出解决办法”。作者是用命令行工作的,他后来解决的办法,是在编译命令中加上“-fno-elide-constructors”参数,例g++ -fno-elide-constructors testReturn.cpp 。

  我的学生还处在用IDE的阶段。本文的价值来了,如何在CodeBlocks下也忽略这个优化项呢?

  在CodeBlocks中,通过菜单依次选:settings->Compiler...,在Global compiler settings部分,选择Other options,在文本框中写入“-fno-elide-constructors”,如图,然后就可以ok啦。





0 0
原创粉丝点击