-
引用作为函数参数和常引用作为函数参数
2016-10-26 15:17:55(2)使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还(1)传递引用给函数与传递指针的效果是一样的。这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。
(2)使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还将调用拷贝构造函数。因此,当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。
(3)使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用"*指针变量名"的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参。而引用更容易使用,更清晰。
--------------------------------------------------
如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。常引用声明方式:const 类型标识符 &引用名=目标变量名;
例1
int a ;
const int &ra=a;
ra=1; //错误
a=1; //正确
例2
string foo( );
void bar(string & s);
那么下面的表达式将是非法的:
bar(foo( ));
bar(“hello world”);
原因在于foo( )和”hello world”串都会产生一个临时对象,而在C++中,这些临时对象都是const类型的。因此上面的表达式就是试图将一个const类型的对象转换为非const类型,这是非法的。
引用型参数应该在能被定义为const的情况下,尽量定义为const 。 -
对象作为函数参数时调用拷贝构造函数、引用做函数参数时只是传递地址
2014-10-13 10:14:24对象也可以作为函数的参数传递给函数,其转递方法与传递其他类型的数据一样,可采用值传递和地址传递两种方法。 值传递:是把对象的拷贝而不是本身传递给函数,函数中对参数对象的任何修改都不会影响调用该函数的...对象也可以作为函数的参数传递给函数,其转递方法与传递其他类型的数据一样,可采用值传递和地址传递两种方法。
值传递:是把对象的拷贝而不是本身传递给函数,函数中对参数对象的任何修改都不会影响调用该函数的对象本身;
地址传递:调用该函数的对象与参数对象共用同一个地址,所以,函数对参数对象的任何修改都会影响调用该函数的对象本身。
注意:在C++中,下面三种对象需要调用拷贝构造函数(有时也称“复制构造函数”)
1) 一个对象作为函数参数,以值传递的方式传入函数体
2) 一个对象作为函数返回值,以值传递的方式从函数返回
3) 一个对象用于给另外一个对象进行初始化(常称为复制初始化)
当用引用变量做参数时,不调用拷贝构造函数,用传递引用的方式给函数传递一个对象的引用时,只传递了该对象的地址,系统消耗较小。在函数体内访问 形参,实际是访问了这个作为实参的对象。例如:void function(CTest & test);
Java中的引用传递是指: 例如:void function(CTest test),没有&号
#include<iostream> using namespace std; class Tr{ public: //Tr(int n):i(n) //构造函数最好这么写 //{} Tr(int n) { i=n; } void set_i(int n) {i=n;} int get_i() {return i;} private: int i; }; void sqr_it1(Tr ob) { ob.set_i(ob.get_i()*ob.get_i()); cout<<"在函数sqr_it1内,形参对象obj的数据成员i="<<ob.get_i(); cout<<endl; } void sqr_it2(Tr *obj) { obj->set_i(obj->get_i()*obj->get_i()); cout<<"在函数sqr_it2内,形参对象obj的数据成员i="<<obj->get_i(); cout<<endl; } int main() { Tr obj(10); cout<<"调用sqr_it前,实参对象obj的数据成员i="<<obj.get_i()<<endl; sqr_it1(obj); cout<<"调用sqr_it1后,实参对象obj的数据成员i="<<obj.get_i()<<endl; sqr_it2(&obj); cout<<"调用sqr_it2后,实参对象obj的数据成员i="<<obj.get_i()<<endl; return 0; }
调用sqr_it前,实参对象obj的数据成员i=10
在函数sqr_it1内,形参对象obj的数据成员i=100
调用sqr_it1后,实参对象obj的数据成员i=10
(此时,由于是以值传递,obj的数据成员i没有变化,还是原先的10)
在函数sqr_it2内,形参对象obj的数据成员i=100
调用sqr_it2后,实参对象obj的数据成员i=100
(此时,由于是以地址传递,obj的数据成员i发生变化,为sqr_it2中的值100)通常的原则是:①对于凡是包含动态分配成员或包含指针成员的类都应该提供拷贝构造函数;②在提供拷贝构造函数的同时,还应该考虑重载"="赋值操作符号。
复制初始化
以下讨论中将用到的例子:
class CExample { public: CExample(){pBuffer=NULL; nSize=0;} ~CExample(){delete []pBuffer;} void Init(int n){ pBuffer=new char[n]; nSize=n;} private: char *pBuffer; //类的对象中包含指针,指向动态分配的内存资源 int nSize; };
这个类的主要特点是包含指向其他资源的指针,pBuffer指向堆中动态分配的一段内存空间。
int main(int argc, char* argv[]) { CExample theObjone; theObjone.Init(40); //现在需要另一个对象,并将它初始化为theObjone CExample theObjtwo=theObjone; ... }
语句"CExample theObjtwo=theObjone;"用theObjone初始化theObjtwo。
回顾一下此语句的具体过程:首先建立对象theObjtwo,并调用其构造函数,然后成员被复制初始化。其完成方式是内存拷贝,复制所有成员的值。完成后,theObjtwo.pBuffer==theObjone.pBuffer。即它们将指向同样的地方,指针虽然复制了,但所指向的空间并没有复制,而是由两个对象共用了。这样不符合要求,对象之间不独立了,并为空间的删除带来隐患。所以需要采用必要的手段来避免此类情况:可以在构造函数中添加操作来解决指针成员的这种问题。所以C++语法中除了提供缺省形式的构造函数外,还规范了另一种特殊的构造函数:拷贝构造函数,一种特殊的构造函数重载。上面的语句中,如果类中定义了拷贝构造函数,在对象复制初始化时,调用的将是拷贝构造函数,而不是缺省构造函数。在拷贝构造函数中,可以根据传入的变量,复制指针所指向的资源。
拷贝构造函数的格式为:类名(const 类名& 对象名);//拷贝构造函数的原型,参数是常量对象的引用。由于拷贝构造函数的目的是成员复制,不应修改原对象,所以建议使用const关键字。提供了拷贝构造函数后的CExample类定义为:
class CExample { public: CExample(){pBuffer=NULL; nSize=0;} ~CExample(){delete []pBuffer;} CExample(const CExample&); //拷贝构造函数 void Init(int n){ pBuffer=new char[n]; nSize=n;} private: char *pBuffer; //类的对象中包含指针,指向动态分配的内存资源 int nSize; }; CExample::CExample(const CExample& RightSides) //拷贝构造函数的定义 { nSize=RightSides.nSize; //复制常规成员 pBuffer=new char[nSize]; //复制指针指向的内容 memcpy(pBuffer,RightSides.pBuffer,nSize*sizeof(char)); }
这样,定义新对象,并用已有对象初始化新对象时,CExample(const CExample& RightSides)将被调用,而已有对象用别名RightSides传给构造函数,以用来作复制。
对象按值传递
下面介绍拷贝构造函数的另一种调用:当对象直接作为参数传给函数时,函数将建立对象的临时拷贝,这个拷贝过程也将调用拷贝构造函数。例如:
BOOL testfunc(CExample obj); testfunc(theObjone); //对象直接作为参数。 BOOL testfunc(CExample obj) { //针对obj的操作实际上是针对复制后的临时拷贝进行的 } 还有一种情况,也是与临时对象有关:当函数中的局部对象作为返回值被返回给函数调者时,也将建立此局部对象的一个临时拷贝,拷贝构造函数也将被调用。 CTest func() { CTest theTest; return theTest; }
总结:当某对象是按值传递时(无论是作为函数参数,还是作为函数返回值),编译器都会先建立一个此对象的临时拷贝,而在建立该临时拷贝时就会调用类的拷贝构造函数。拷贝构造函数的实现: -
C++ 函数参数应该传递对象还是对象引用?函数应该返回对象还是对象引用?
2020-03-15 16:07:48首先来看,函数参数方面: 记住:编写使用对象作为参数的函数时,应按引用而不是按值来传对象,原因如下 1.提高效率,按值传递(直接传递对象)涉及到生成了临时拷贝,即调用复制构造函数,然后调用析构函数,调用...在初学C++的时候,学到引用结合函数运用的部分,一直有一个疑惑:函数的参数应该是对象还是对象的引用?返回值选择返回对象还是对象的引用?二者又有什么区别?
首先来看,函数参数方面:
记住:编写使用对象作为参数的函数时,应按引用而不是按值来传对象,原因如下1.提高效率,按值传递(直接传递对象)涉及到生成了临时拷贝,即调用复制构造函数,然后调用析构函数,调用这些函数需要时间,比起直接传递对象的引用花费的时间要多得多
2.在继承中使用虚函数时,被定义为接受基类引用的函数可以接受派生类对象的引用(基类指针或引用可以指向派生类)
其次,返回值方面,有两种情况:
1.当该函数返回的是通过引用或指针传递的对象,则返回值应为对象的引用,如下
A & Compare(const A &a)const //返回A类型的引用 { if(this->weight>a.weight) return *this //返回通过指针传递的对象 else return a //返回通过引用传递的对象 }
2.当该函数返回的是在函数中创建的临时对象时,则应返回对象,通常用于重载运算符‘+ - × ÷’的时候,如下
A operator + (const A &a)const //重载‘+’,返回A类型对象 { return A(this->weight+a.weight)//返回了一个临时对象 }
-
c++中对象的引用作为函数的参数
2020-12-13 14:38:18#include using namespace std; class A { public : A(){x=0;y=0;} A(int i,int j) { x=i;y=j; } void SetValue(int i,int j) { x=i;y=j; } void Disp() { cout<...r) //对象引用作形参 { r.SetVal#include
using namespace std;
class A
{
public :
A(){x=0;y=0;}
A(int i,int j)
{
x=i;y=j;
}
void SetValue(int i,int j)
{
x=i;y=j;
}
void Disp()
{
cout<<x<<","<<y<<endl;
}
private:
int x,y;
};
void fun(A &r) //对象引用作形参
{
r.SetValue(10, 20);
}
int main(int argc, const char * argv[]) {
A a(1,2);
fun(a);
a.Disp();
return 0;
}
输出:
10,20
Program ended with exit code: 0 -
引用作为函数参数有哪些特点
2019-04-28 17:26:33问题:将“引用”作为函数的参数有哪些特点? 分析: 这道题不仅考查了对引用的理解和应用,同时考查了对函数的三种传递参数方式基本概念的理解。总结起来,有如下特点: • 传递引用给函数与指针的效果是一样的... -
c++对象作为函数参数
2016-02-01 12:38:32c++对象作为函数参数也分为值传递和引用传递: 对象也可以作为函数的参数传递给函数,其转递方法与传递其他类型的数据一样,可采用值传递和地址传递两种方法。 值传递时是把对象的拷贝而不是本身传递给函数... -
对象作为函数参数
2016-02-20 11:00:48You can pass objects by value or by reference.(对象作为函数参数,可以按值传递也可以按引用传递)//主函数 #include #include "Circle2.h" using namespace std;void printCircle(Circle c){//接受对象c cout ... -
C++引用作为函数参数
2017-01-17 19:14:32引用很容易与指针混淆,它们之间有三个主要的不同: ...2.一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。 3.引用必须在创建时被初始化。指针可以在任何时间被初始化。 -
C++学习-引用作为函数参数
2015-09-28 14:49:40在我们的编程过程中,我们经常将引用用作函数参数, 使得函数中的变量名成为调用程序中的变量的别名.这种传递参数的方法成为按引用传递. 但是在函数中使用引用,往往会改变被引用对象的值.所以引入const.将引用... -
C++对象作为函数参数
2014-08-20 08:58:04关于C/C++中基本类型(如:int,int*等)作为函数参数时,是通过将该变量的值压栈来进行参数传递;本文通过C++反汇编代码分析了当对象作为函数参数时(该形参非引用或指针),参数如何传递以及此时栈帧的结构。 -
c++之指针和引用作为函数参数传递时的区别
2020-06-03 09:15:57之前写过c++之值传递、引用传递、指针传递,今天再单独区分一下指针和引用作为函数参数传递时的区别。 本文参考浅谈C++中指针和引用的区别 一、指针作为函数参数传递时 1、类似于值传递,传入函数的指针只是原指针的... -
C++中,对象作为函数参数的几种情况
2020-10-07 09:37:34Passing Objects to Functions (对象作为...(对象作为函数参数,可以按值传递,也可以按引用传递) (1) Objects as Function Return Value(对象作为函数参数) // Pass by value void print( Circle c ) { //作为函数参 -
c++对象引用作函数的参数
2020-12-13 15:26:54#include using namespace std; class A { public: A(){x=0;y=0;} A(int i,int j) { x=i;y=j; } void SetValue(int i,int j) { x=i;y=j; } void Disp() { cout<...r) //对象引用作为形参 { r.S -
C++中使用引用作为函数参数的优点
2015-10-27 17:33:002.使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的 副本;如果传递的是对象,还... -
指针的引用作为函数参数有啥用?
2014-02-17 20:05:00一句话总结 用指针的引用作为某函数的参数来传递,其目的就是为了在这个函数里面改变该指针的值(就是改变指针所指向的对象)。 -
引用类型作为函数参数何解
2019-01-03 10:58:00在向函数传递引用类型的参数时,相当于把引用类型的地址复制给函数内的一个局部变量,所以局部变量和传入的参数会指向内存中的同一个对象。 局部变量的变化也会映射到传入参数 function setAge(obj){ obj.age =... -
C++使用对象作为函数参数(使用this指针)
2019-10-07 10:56:18今天在学习过程中,发现在C++使用对象作为函数参数进行传递时,实参向形参采用传值的方法进行传递,但是在函数中使用this指针,分别指向对象的数据成员,在子函数结束后返回main函数时,依然能够改变实参(对象)的... -
临时函数对象作为函数参数 以及 类模板编程的文件组织
2018-01-13 22:58:431、当临时函数对象作为函数参数时,记住一点:临时对象的返回值是右值,当然临时函数对象的返回值也是右值,此时的形参要么加const,要么用右值引用&&; 2、使用类模版的文件组织:网上的说法是把类的定义以及类中... -
C# 引用类型作为函数参数时
2015-07-30 17:54:58C# 引用类型作为函数参数时 在探讨本文的主题之前,先来介绍下C#中的值类型和引用类型 众所周知C#中有值类型和引用类型,值类型有基础数据类型(诸如int,double,bool等)、结构体、枚举,引用类型有接口、... -
c++ 对象指针参数和对象引用参数02
2015-04-19 16:29:00对象指针作为函数参数和对象引用作为函数参数都比对象作为函数参数要用的更为普遍 传对象指针和传对象引用作为实参,那么实参在函数里发生了变话,那么相应的对象本身也会发生变化,二传递对象本身作为实参的话,... -
4,将引用作为函数的参数有哪些特点
2017-10-06 12:40:28我总结了一下,将引用作为函数参数有如下特点(就不上代码了): 1,传递引用和传递指针的作用其实是一样的。这时,被调函数的形参就被当成原来的主调函数实参变量或对象的一个别名来使用,所以在被调函数中对... -
将“引用”作为函数参数有哪些特点
2019-09-25 09:37:13这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。 (2)使用引用传递函数的参数,在内存中并没有... -
R语言-引用函数对象作为参数
2017-03-17 17:41:22问题描述如何在在R的函数中通过字符串调用别的函数。 以下面为例子:testFun (Fun){ x Fun(x) }解法这个问题没什么其实很笨,就是想记录一下。#1. 直接调用 testFun (Fun){ x Fun(x) } testFun(sum) # 5050 ... -
C++第八章__内联函数__引用变量_将引用变量作为函数参数__使用引用作为形参,会改变对应实参的值(左值的概念...
2019-09-27 02:00:15将引用变量作为函数参数 使用引用作为形参,会改变对应实参的值以及左值的概念 将引用应用于结构 为何要使用引用 将引用用于类和对象 对象、继承和引用 何时使用按值传递、按指针传递和按引用传递 默认参数 ...
-
Magisk-v22.0.apk.zip
-
【布道者】Linux极速入门
-
【ssm项目源码】医院信息管理系统.zip
-
现在的直播软件开发大概需要多久
-
CIF从价关税计算器_简易版
-
MySQL 高可用工具 heartbeat 实战部署详解
-
PAT甲级题解 1013
-
华为1+X——网络系统建设与运维(中级)
-
Micrium-uC-Probe-Setup-Release-4.8.2.0
-
Paint in 3D v1.9.14
-
MySQL 高可用(DRBD + heartbeat)
-
嵌入式内存优化手段
-
剑指offer-2.28-8
-
IT6322-UM-CN-222356.pdf
-
450. 删除二叉搜索树中的节点
-
【ssm项目源码】商店管理系统.zip
-
飞行模拟训练设备质量评估管理系统软件
-
mysql开启慢查询日志
-
php如何将对象转换为数组
-
枚举练习_用户在线状态查询