类型:C++ & Qt4,创建时间:十二月 30, 2011, 7:43 p.m.

标题无“转载”即原创文章,版权所有。转载请注明来源:http://hgoldfish.com/blogs/article/19/。

最近写C++程序经常郁闷传参数的时候应该传值、传引用还是传指针。

  • 传值 :int func(User u);
  • 传指针: int func(User* u);
  • 传引用: int func(User& u);

传值是传参数最常见的方法,相当简单,是C++的基础传参方法。如果参数是整形、字符等基础类型,用传值的方法是最快的,也是最简单的。它的缺陷是对于一些很大的对象,比如上面定义的User对象,使用传值方法时,内存开销比较大,会重新创建一个User对象。还有一个情况,如果User是多态的,这样传参数会出问题。因为C++会调用新创建的User对象的复制构造函数,而默认的复制构造函数只会把需要的属性复制到新对象里,引起所谓的切割现象。

在C++古生代,传指针是传值之外的唯一方法。与传值相比较,需要考虑内存管理的问题,在栈上分配的对象通常就不能传递指针,因为函数返回之后栈上的对象会被析构,这时的指针就会成为野指针,引用它会造成内存访问异常。即使对象是在堆上分配的,传指针里也同样要考虑分配错误等问题。不过,与传值相比,传指针对付大型对象和多态对象很有效,而且,使用指针形式传递的变量在运行过程中可以被修改。

传引用似乎结合了两者的优点。与传指针一样,传引用能很好地对付大型对象多态对象,而且相对于传指针,传引用通常是不需要考虑内存管理的问题,因为只能使用另一个已经初始化的变量来初始化引用。一切看起来似乎都很美好。不过优点往往也是缺点,引用类型的变量不适合作为类的属性,因为引用一旦初始化就不能改变其指向的对象。考虑对象的一个属性:操作日志表中存在一个User类型的字段,名为operator

class Log
{
    User operator;
};

现在我们要给operator属性写它的accessor。传引用的话应该改成这样子:

class Log
{
    User& operator;
public:
    void setUser(User& u){operator=u;}
};

这样做的问题是,这个类根本不能实例化。比较好的做法是把operator改成User类型。像这样:

class Log
{
    User operator;
public:
    void setUser(User& u){operator=u;}
};

这样做的问题也很明显,如果User是多态的话,仍然会引起切割现象。那就这样吧:

class Log
{
    User* operator;
public:
    void setUser(User& u){operator=&u;}
};

这通常倒是没什么问题。只是传入的u很可能是分配在栈上的对象,operator随时可能成为野指针,很容易引发错误。有什么办法没有?想了很久,看来是没有吧。不过为了避免调用者误以为operator可以分在栈上,还是改成传指针比较好。反正此时传引用相对于传指针已经没有任何优势了。

这真是一件很糟糕的一件事,C++这种面向底层的语言真是让人很痛苦。总结一下吧:

基础类型传值、普通的非多态的对象传引用,多态对象以及分配在堆上的对象传指针。

标题无“转载”即原创文章,版权所有。转载请注明来源:http://hgoldfish.com/blogs/article/19/

转载自 老鱼的博客

传参数应该用哪种形式——值、引用、指针?的更多相关文章

  1. 《Java中方法的参数传递方式只有一种:值传递》

    //方法的参数传递机制(1):基本类型做形参的传递. class PrimitiveTransferTest { public static void swap(int a,int b) { //下面 ...

  2. c语言 函数传输传递的三种方式(值、指针、引用)

    本文摘自<彻底搞定c指针> 一.三道考题开讲之前,我先请你做三道题目.(嘿嘿,得先把你的头脑搞昏才行……唉呀,谁扔我鸡蛋?)考题一,程序代码如下:void Exchg1(int x, in ...

  3. 【转】C++11 标准新特性: 右值引用与转移语义

    VS2013出来了,对于C++来说,最大的改变莫过于对于C++11新特性的支持,在网上搜了一下C++11的介绍,发现这篇文章非常不错,分享给大家同时自己作为存档. 原文地址:http://www.ib ...

  4. c++ 11 移动语义、std::move 左值、右值、将亡值、纯右值、右值引用

    为什么要用移动语义 先看看下面的代码 // rvalue_reference.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #includ ...

  5. C++11 标准新特性: 右值引用与转移语义

    文章出处:https://www.ibm.com/developerworks/cn/aix/library/1307_lisl_c11/ 新特性的目的 右值引用 (Rvalue Referene) ...

  6. c++右值引用以及使用

    前几天看了一篇文章<4行代码看看右值引用> 觉得写得不错,但是觉得右值引用的内容还有很多可以去挖掘学习,所以总结了一下,希望能对右值引用有一个更加深层次的认识 一.几个基本概念 1.1左值 ...

  7. SPRING IN ACTION 第4版笔记-第五章BUILDING SPRING WEB APPLICATIONS-004-以query parameters的形式给action传参数(@RequestParam、defaultValue)

    一. 1.Spring MVC provides several ways that a client can pass data into a controller’s handler method ...

  8. thinkphp 3.2.3 入门示例2(URL传参数的几种方式)

    原文:thinkphp中URL传参数的几种方式 在thinkphp中,url传参合asp.net中原理类似,下面就单个参数和多个参数传递方式进行一个简单讲解 1.传单个参数 单个参数这种比较简单,例如 ...

  9. Struts2中Action接收参数的四种形式

    1.Struts2的Action接收参数的三种形式.      a. 使用Action的属性接收(直接在action中利用get方法来接收参数):                   login.js ...

随机推荐

  1. go-hbase的Scan模型源码分析

    git地址在这里: https://github.com/Lazyshot/go-hbase 这是一个使用go操作hbase的行为. 分析scan行为 如何使用scan看下面这个例子,伪代码如下: f ...

  2. 利用密钥通过ssh互访

    dir(192.168.131.132):作为client rs1(192.168.131.110)和 rs2(192.168.131.131):作为server端     1.dir 运行命令:   ...

  3. jsp+servlet 中文乱码问题

    一. 由于doget和dopost的处理方式不同,在做servlet的时候遇到这样一个问题:用doPost获得的参数只要加上“request.setCharacterEncoding("ut ...

  4. javaEE-----org.springframework.dao.InvalidDataAccessApiUsageException: Write operation

    org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read ...

  5. Objective-C 变量和基本的数据类型

    转自:http://blog.csdn.net/mengxiangyue/article/details/11369679 OC中有如下基本数据类型: int:声明整型变量 double:声明双精度变 ...

  6. Busybox下tftp命令使用详解

    http://blog.chinaunix.net/uid-375398-id-1991686.html Busybox下的tftp命令可以用来进行单文件传输.使用的时候,是把电脑作为服务器Serve ...

  7. 解决Win7 软件图标不显示--Win7图标异常,快捷方式不显示解决方法

    电脑症状:WIN7的系统,桌面上的图标显示的不正常,快捷方式显示的是未知程序.看不到程序默认图标,快捷方式图标不显示. 解决方法:删除程序图标缓存即可.   将下面的内容复制到记事本保存为“Repai ...

  8. Mysql关键字 Mysql保留字列表 Mysql字段名

    Mysql保留字列表.吠品整理. 尝试使用一个识别符,例如使用嵌入式MySQL 数据类型或函数名作为表名或列名,例如TIMESTAMP 或GROUP,会造成一个常见问题.允许你这样操作( 例如,ABS ...

  9. Java Web之Servlet

    Servlet参考文献: 1.http://www.cnblogs.com/luoxn28/p/5460073.html 2.http://www.cnblogs.com/xdp-gacl/p/376 ...

  10. PMP 第十一章 项目风险管理

    1规划风险管理 2识别风险 3 风险定性分析 4风险定量分析 5规划风险应对 6监控风险 1.项目风险是什么?已知未知风险.未知未知风险对应应急储备和管理储备的关系.风险承受力和风险偏好是什么? 2. ...