繁体   English   中英

什么时候在C ++中返回指针,标量和引用?

[英]When to return a pointer, scalar and reference in C++?

我正在从Java迁移到C ++,并对语言的灵活性有些困惑。 一点是,有三种存储对象的方式:指针,引用和标量(如果我正确理解,则存储对象本身)。

我倾向于在可能的地方使用引用,因为它与Java越接近越好。 在某些情况下,例如,派生属性的获取程序,这是不可能的:

MyType &MyClass::getSomeAttribute() {
    MyType t;
    return t;
}

这不会编译,因为t仅存在于getSomeAttribute()的范围内,并且如果我返回对其的引用,则在客户端可以使用它之前它不会指向任何地方。

因此,我有两个选择:

  1. 返回一个指针
  2. 返回标量

返回一个指针看起来像这样:

MyType *MyClass::getSomeAttribute() {
    MyType *t = new MyType;
    return t;
}

这是可行的,但是客户端必须检查此指针是否为NULL才能真正确定,这对于引用不是必需的。 另一个问题是调用者必须确保将t释放,如果可以避免的话,我宁愿不处理它。

另一种方法是返回对象本身(标量):

MyType MyClass::getSomeAttribute() {
    MyType t;
    return t;
}

这非常简单,正是我在这种情况下想要的:感觉像是一个引用,不能为null。 如果该对象超出了客户端代码的范围,则将其删除。 很方便。 但是,我很少看到有人这样做,这是有原因的吗? 如果我返回标量而不是指针或引用,是否会有某种性能问题?

解决此问题的最常见/最优雅的方法是什么?

按值返回。 编译器可以优化副本,因此最终结果就是您想要的。 创建一个对象,并将其返回给调用者。

我认为您很少看到别人这样做的原因是因为您正在查看错误的C ++代码。 ;)大多数来自Java的人都对这样做感到不自在,因此他们到处都是new 然后它们到处都是内存泄漏,必须检查NULL以及可能引起的所有其他问题。 :)

值得指出的是,C ++引用与Java引用几乎没有共同之处。 Java中的引用与指针非常相似(可以重新定位,也可以将其设置为NULL)。 实际上,唯一真正的区别是指针也可以指向垃圾值(如果未初始化,或者指向超出范围的对象),并且可以对指针进行指针算术运算。数组。 C ++引用是对象的别名。 Java引用的行为并非如此。

很简单,尽可能避免使用new指针和动态分配。 请改用值,引用和自动分配的对象。 当然,您不能总是避免动态分配,但是这应该是最后的选择,而不是第一选择。

按值返回可能会导致性能下降,因为这意味着需要复制对象。 如果它是一个大对象(如列表),则该操作可能会非常昂贵。

但是现代编译器非常擅长于避免这种情况的发生。 C ++标准明确声明在某些情况下允许编译器取消复制。 与您提供的示例代码相关的特定实例称为“返回值优化”。

就个人而言,当我返回成员变量时,我通过(通常为const)引用返回,并在需要动态分配某些内容时返回某种类型的智能指针对象(通常为::std::auto_ptr )。 否则,我将按价值返回。

我也经常有const引用参数,这在C ++中很常见。 这是传递参数并说“该功能不允许触摸”的一种方式。 基本上是一个只读参数。 但是,仅应将其用于比单个整数或指针更复杂的对象。

我认为Java的一大变化是const非常重要且经常使用。 学习了解它,并使其成为您的朋友。

我还认为Neil的答案是正确的,它指出尽可能避免动态分配是一个好主意。 您不应该过多地扭曲设计以使之实现,但是您绝对应该选择不必进行设计的选择。

按值返回是C ++中常见的做法。 但是,在传递对象时,将通过引用传递。

 main()
   {

       equity trader;

       isTraderAllowed(trader);

       ....
    }

    bool isTraderAllowed(const equity& trdobj)
    {
             ... // Perform your function routine here.
    }

上面是通过引用传递对象的简单示例。 实际上,您将有一个名为isTraderAllowed的方法用于类权益,但是我向您展示了按引用传递的实际用法。

关于通过值或引用传递的一点:
考虑到优化,假设一个函数为inline ,如果其参数声明为“ const DataType objectName”,则该DataType甚至可以是基元,也不会涉及任何对象副本; 如果将其参数声明为“ const DataType&objectName”或“ DataType&objectName”,则DataType甚至可以是原语,也不会涉及地址获取或指针。 在上述两种情况下,输入参数都直接在汇编代码中使用。

关于参考的一点:
引用并不总是一个指针,例如,当您在函数主体中具有以下代码时,该引用就不是指针:

int adad=5;
int & reference=adad;  

关于按值返回的一点:
正如某些人提到的,使用具有优化功能的良好编译器,按任何类型的值返回都不会导致多余的副本。

关于按参考归还的要点:
对于内联函数和优化,按引用返回将不涉及地址获取或指针。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM