C++拷贝构造的优化

来源:互联网 发布:软件静默安装 编辑:程序博客网 时间:2024/05/29 07:38

对于拷贝构造来说,归根结底,落脚点在构造函数上。所以调用拷贝构造函数的时候,一定是这个对象不存在的时候,比如下面这句

A a =A(10)

那么,a是不存在的,而且是通过其它的A对象构造出来的,那么则调用的是拷贝构造函数。如果是

 A a(1); a =  A(10);

那么这里就调用的是赋值操作符,因为a是已经存在的对象了,不需要构造了。

那么,接下来再讨论一下拷贝构造的优化问题。如果有以下代码:
代码 1:

#include <iostream>using namespace std;static int i=0;class A {    public:        A(){cout<<"A::A()"<<endl;         }        ~A(){cout<<"A::~A()"<<endl;        }        A(const A& o){            i++;            cout<<"A::A(const A& 0)"<<endl;        }    private:        int t;};A f(A a) {     return a;}int main() {    A a1;    a1=f(a1);    return 0;}//main()函数中调用了2次A的拷贝构造函数,1次A的赋值运算符函数的重载。 

解释:1次A的赋值运算符函数重载(类中没有定义是调用默认的重载运算符)。
这里写图片描述

代码2:

#include <iostream>using namespace std;static int i=0;class A {    public:        A(){cout<<"A::A()"<<endl;         }        ~A(){cout<<"A::~A()"<<endl;        }        A(const A& o){            i++;            cout<<"A::A(const A& 0)"<<endl;        }    private:        int t;};A f(A a) {     return a;}int main() {    A a1;    A a2=f(a1);    return 0;}//main()函数中调用了2次A的拷贝构造函数,0次A的赋值运算符函数的重载。

解释:在创建对象的同时赋值给该对象为拷贝构造(因为a2对象原先不存在),而不是赋值运算符的重载,所以赋值运算符的重载0次。
这里写图片描述

代码3:

#include <iostream>using namespace std;static int i=0;class A {    public:        A(){cout<<"A::A()"<<endl;         }        ~A(){cout<<"A::~A()"<<endl;        }        A(const A& o){            i++;            cout<<"A::A(const A& 0)"<<endl;        }    private:        int t;};A f(A a) {     return a;}int main() {    A a1;    A a2=f(f(a1));    return 0;}//main()函数中调用了3次A的拷贝构造函数,0次A的赋值运算符函数的重载。

解释:在函数调用过程中,实际上优化了两次:第一次发生在第一次return a的时候,同时将return的临时变量temp1作为函数参数再一次传入,相当于A a = temp1(构造函数并优化一次);第二此发生在第二次return a的时候,同时将return的临时变量temp2作为成员对a2初始化,相当于 A a2 = temp2(调用构造函数并优化一次)。
这里写图片描述

代码4

#include <iostream>using namespace std;static int i=0;class A {    public:        A(){cout<<"A::A()"<<endl;         }        ~A(){cout<<"A::~A()"<<endl;        }        A(const A& o){            i++;            cout<<"A::A(const A& 0)"<<endl;        }    private:        int t;};A f (A a) {    cout<<"i = "<<i<<endl;     cout<<"end"<<endl;     return a;}int main() {    cout<<"i = "<<i<<endl;    A a1;    f(a1);    return 0;}//调用两次拷贝构造函数

解释:在函数参数的时候调用一次,return的时候调用一次。

代码5:

#include <iostream>using namespace std;static int i=0;class A {    public:        A(){cout<<"A::A()"<<endl;         }        ~A(){cout<<"A::~A()"<<endl;        }        A(const A& o){            i++;            cout<<"A::A(const A& 0)"<<endl;        }    private:        int t;};A f (A a) {    cout<<"i = "<<i<<endl;     cout<<"end"<<endl;     return a;}A& g (A& a) {    cout<<"i = "<<i<<endl;     cout<<"end"<<endl;     return a;}int main() {    cout<<"i = "<<i<<endl;    A a1;    f(g(a1));    return 0;}//调用两次拷贝构造函数

解释:在g()函数中,传入和返回都是引用,以为着没有新的对象生成,所以不会调用拷贝构造函数,而f()函数的调用和代码4是一样的,故调用两次拷贝构造函数。

原创粉丝点击