• 传参数应该用哪种形式——值、引用、指针?


    类型: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/

    转载自 老鱼的博客

  • 相关阅读:
    3名百度 ,京东,腾讯被辞退的高级Android工程师现在怎么了?30岁真的是“罪”吗
    Python 开发者在迁移到 Go 前需要知道的事情
    centos7 常用命令--查看当前用户的4种方法
    Centos7找不到ifconfig和netstat命令
    Centos 7 修改日期和时间的命令
    如何利用MobaX同时处理多台虚拟机输入相同命令如何利用MobaX同时处理多台虚拟机输入相同命令
    配置坑了我好久:Logback按天生成文件失效
    quartz系列文章
    SpringBoot使用多实例QUARTZ出现重复执行问题
    IDEA多个springboot项目启动修改端口
  • 原文地址:https://www.cnblogs.com/VVingerfly/p/6082903.html
Copyright © 2020-2023  润新知