返回对数据成员的引用

Returning a reference to a data member

本文关键字:引用 数据成员 返回      更新时间:2023-10-16

看完后:

返回c++引用变量的做法是邪恶的吗?

和其他一些关于引用的资源,我想知道这样的东西是否可以,或者我应该返回一个指针?

#include <iostream>
class engine
{
public:
  int cc;
};

class car
{
protected:
  engine eng;
public:
  car (void) : eng()
  {
    eng.cc = 500;
  }
  const engine& get_engine(void) const
  {
    return eng;
  }
};

int main (void)
{
  car c = car();
  engine en = c.get_engine();

  std::cout << en.cc << std::endl;
}

:

如果我改变

一行会有什么不同?

engine en = c.get_engine();

engine& en = c.get_engine();

都编译并给出相同的输出,但有任何微妙/不那么微妙的差异吗?

编辑:正如Vlad从莫斯科指出的,最后一个应该是const engine& en = c.get_engine();

答案取决于您想要建模的内容:

  • 如果一个引擎不能在它的汽车的上下文中存在,如果一个汽车不能在没有引擎的情况下存在,返回一个引用是好的——这意味着当你使用它的引擎时,汽车将存在。
  • 如果一个引擎可以存在于它的汽车上下文之外,你最好返回一个指针(最好是一个智能指针)。这样,删除相应的汽车并不会删除引擎。
  • 同样的道理,如果一辆车没有引擎也可以存在:你需要返回一个指针,因为没有空引用这样的东西(hack在这里不算)

当然,这些只是现实的模型——在现实中,没有发动机的汽车和没有汽车的发动机都存在。如果合适的话,你甚至可以在不同的车之间交换引擎。然而,将现实建模到这个层次需要您付出更多的努力,因此您需要决定您的模型能走多远。

engine en = c.get_engine();engine &en = c.get_engine();的区别在于,第一个表达式复制了c的引擎,而第二个表达式引用了原位的引擎。除此之外,这意味着对引擎副本的操作不会自动反映在原始引擎中,因为它们不是同一个对象。另一个结果是,副本在删除汽车后仍然存在,而引用却不能。

区别在于,在第二种情况下,不会调用复制构造函数。

你只需要写

const engine& en = c.get_engine();

你的代码是O'k

从你引用的SO帖子,给出的例子是:

int& getInt(void)
{
    int i;
    return i;
}

那肯定不好。你正在返回一个对象的引用,当你从函数返回时该对象将消失。

对你来说,

const engine& get_engine(void) const
{
  return eng;
}

这是返回对象引用的一个完全有效的用法。

使用

engine& en = c.get_engine();