zoukankan      html  css  js  c++  java
  • C++_类和动态内存分配4-有关返回对象的说明

    返回方式

    1. 返回指向对象的引用;
    2. 指向对象的const引用;
    3. const对象;

     ===============================================

    返回指向const对象的引用

    假如要编写函数Max(),它返回两个Vector对象中较大的一个,其中Vector是第11章开发的一个类。

    Vector force1(50, 60);

    Vector force2(10,70);

    Vector max;

    max = Max(force1, force2);

     

    //version 1

    Vector Max(const Vector & v1, const Vector & v2)

    {

           if (v1.magval() > v2.magval())

                  return v1;

           else

                  return v2;

    }

     

    //version 2

    const Vector & Max(const Vector & v1, const Vector & v2)

    {

           if (v1.magval() > v2.magval())

                  return v1;

           else

                  return v2;

    }

    返回对象将调用复制构造函数,而返回引用不会。因此第二个版本所做的工作更少,效率更高。引用指向的对象应该在调用函数执行时同时存在。

    注意v1和v2被声明为const引用,所以返回类型必须为const,这样才匹配。

    =============================================

    返回指向非const对象的引用

    Operator=()的返回值作用域连续赋值

    String s1(“Good stuff”);

    String s2,s3;

    s3=s2=s1;

    上述代码中,s2.operator=()的返回值被赋给s3。为此,返回String对象或String对象的引用都是可行的。

     

    Operator<<()的返回值用于串接输出

    String s1(“Good stuff”);

    cout << s1 << “is coming!”;

           operator<<(cout,s1)的返回值成员一个用于显示字符串“is coming!”的对象。返回类型必须是ostream &,而不能仅仅是ostream。如果使用返回类型ostream,将要求调用ostream类的赋值构造函数,而ostream没有公有的赋值构造函数。幸运的是,返回一个指向cout的引用不会带来任何问题,因为cout已经在调用函数的作用域内。

    =================================

    返回对象

           如果被返回的对象是被调用函数的局部变量,则不应该按引用方式去返回它,因为在被调用函数执行完毕时,局部对象将调用析构函数。因此,当控制权回到调用函数时,引用指向的对象将不再存在。在这种情况下,应返回对象而不是引用。

           通常,被重载的算术运算符属于这一类。

    Vector force1();

    Vector force2();

    Vector net;

    net = force1+force2;

           返回的不是force1,也不是force2,force1和force2在这个过程中应该保持不变。因此,返回值不能是指向在调用函数中已存在的对象的引用。相反,在Vector::operator+()中计算得到的两个矢量和被存储在一个新的临时对象中,该函数也不应返回指向该临时对象的引用,而应该返回实际的Vector对象,而不是引用。

           在这种情况下,存在调用复制构造函数来创建被返回的对象的开销,然而这时无法避免的。

    Vector Vector::operator+(const Vector & b) const

    {

           Return Vector(x+b.x, y+b.y)

    };

    ========================================

    返回const对象

    前面的Vector::operator+()的定义中有一个奇异的属性,

    net = force1 +force2; //语句1

    force1 +force2 =net; //语句2

     

    这种代码都可行,是因为复制构造函数将创建一个临时对象来表示返回值。因此,在前面的代码中,表达式force1+force2的结果为一个临时对象。在语句1中,该临时对象被赋给一个net;在语句2中,net被赋给该临时对象。

           如果您担心这种行为引发滥用。有个简单的解决方案,就是把返回类型声明为const Vector。那么语句2就非法了,因为返回对象无法被赋值,只能赋值给别人。

     

           总是,如果方法或函数要返回局部对象,就必须要返回对象,而不是返回对象的引用。这种情况下将使用赋值构造函数来生成返回的对象。这样的开销是不可避免的,也是必须的。

           如果方法或函数要返回一个没有公有复制构造函数的类(例如ostream类)的对象,它必须返回一个指向这种对象的引用。[ZJ2] 

           最后,有些方法和函数可以返回对象,也可以返回指向对象的引用,在这种情况下,应首选引用,因为其效率更高。


    不能返回局部对象的引用。很危险,因为局部对象会过期,引用会失效。

  • 相关阅读:
    websocket协议
    vue组件之间的传值
    vue中非父子组件的传值bus的使用
    $.proxy的使用
    弹性盒模型display:flex
    箭头函数与普通函数的区别
    粘贴到Excel的图片总是有些轻微变形
    centos rhel 中文输入法的安装
    vi ,默认为 .asm .inc 采用nasm的语法高亮
    how-to-convert-ppk-key-to-openssh-key-under-linux
  • 原文地址:https://www.cnblogs.com/grooovvve/p/10493518.html
Copyright © 2011-2022 走看看