欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用值和用地址传递对象

程序员文章站 2022-07-14 18:24:36
...
[size=medium]今天学习《从新手到高手C++全部精华教程》,http://www.iteye.com/topic/1126275

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

举例如下:[/size]
#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;
}

[size=medium]按值传递对象,如上图所示,结果如下[/size]

[img]http://dl.iteye.com/upload/attachment/0076/4393/08cd61b9-a890-39e3-94ab-108f24ba2967.jpg[/img]


[size=medium]按地址传递:
按地址传递对象:[/size]
#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;
}

结果如下:

[img]http://dl.iteye.com/upload/attachment/0076/4395/9ff9957d-f076-36fa-8463-b23f5f1eafab.jpg[/img]


[size=medium]若func函数返回的不是对象,而是指向该对象的指针,则如下:[/size]
#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;
}

[size=medium]结果如下:[/size]

[img]http://dl.iteye.com/upload/attachment/0076/4397/7d17b193-28cf-3d4c-8136-395090049744.jpg[/img]
相关标签: c++ 传递对象