`
hello_wangfeng
  • 浏览: 31790 次
社区版块
存档分类
最新评论

用值和用地址传递对象

阅读更多
今天学习《从新手到高手C++全部精华教程》,http://www.iteye.com/topic/1126275

“传值和传地址的区别是,传值由于是传递的原始变量的副本,因此不会改变原始变量的值,而传地址则可以改变原始变量的值。假如仅仅是传递变量的话,采用指针或引用这种传地址的方式的优势并不明显,但是如果传递的是较大的对象的话,那么传地址的优势是十分明显的。这时因为,在用传值的方式传递一个对象时,会像传变量一样建立一个该对象的拷贝,而从函数返回一个对象时,也要建立这个返回的对象的一个拷贝。但是若对象的数据很大时,这种内存的开销是相当可观的。然而,按值传递的开销远不如此,由于在传递对象的过程中需要复制对象,因此会默认调用复制构造函数,该函数就是要创建该对象的副本。同时,若返回的仍是该对象,那么仍按照传值的方式,就又会调用复制构造函数创建该对象的临时副本,当该值成功返回调用程序后,在调用该对象的析构函数删除临时拷贝并释放内存。”

举例如下:

#include<iostream>
using namespace std;

class A{
public:
    A(){cout<<"执行构造函数创建一个对象"<<endl;}
    A(A&){cout<<"执行复制构造函数创建该对象的副本"<<endl;}
    ~A(){cout<<"执行析构函数删除该对象"<<endl;}
};
A func(A one){
    return one;
}
int main(){
A a;
func(a);
    return 0;
}

按值传递对象,如上图所示,结果如下




按地址传递:
按地址传递对象:

#include<iostream>
using namespace std;

class A{
public:
    A(){cout<<"执行构造函数创建一个对象"<<endl;}
    A(A&){cout<<"执行复制构造函数创建该对象的副本"<<endl;}
    ~A(){cout<<"执行析构函数删除该对象"<<endl;}
};
A func(A *one){
    return *one;  //如果是return one;的话,则是错误的,因为one是指针,而函数func的返回类型是对象
}
int main(){
A a;
func(&a);
    return 0;
}

结果如下:




若func函数返回的不是对象,而是指向该对象的指针,则如下:
#include<iostream>
using namespace std;

class A{
public:
    A(){cout<<"执行构造函数创建一个对象"<<endl;}
    A(A&){cout<<"执行复制构造函数创建该对象的副本"<<endl;}
    ~A(){cout<<"执行析构函数删除该对象"<<endl;}
};
A* func(A *one){  //将func函数的返回类型改为指针后,在调用该函数的时候就不用再次调用构造函数了
    return one;  //同时,函数的返回值必须也是指针才可以
}
int main(){
A a;
func(&a);  //按地址传递,则实参必须是地址,所以用&a,同时,形参必须要接收地址,所以是*one
    return 0;
}

结果如下:

  • 大小: 22 KB
  • 大小: 17 KB
  • 大小: 11.1 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics