返回对数据成员的引用

时间:2014-05-05 19:19:07

标签: c++ reference

读过这个:

Is the practice of returning a C++ reference variable, evil?

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

#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();

编译并提供相同的输出,但是有任何微妙/不那么细微的差异吗?

编辑:正如莫斯科的弗拉德所指出的那样,最后一个应该是const engine& en = c.get_engine();

3 个答案:

答案 0 :(得分:4)

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

  • 如果发动机不能存在于汽车的上下文之外,并且如果没有发动机就不能存在汽车,那么返回参考就可以了 - 这意味着当您使用其发动机时汽车将存在。
  • 如果引擎可以存在于其汽车的上下文之外,那么最好返回一个指针(最好是一个智能指针)。这样删除相应的汽车就不会删除引擎。
  • 如果汽车可以在没有引擎的情况下存在,同样如此:你需要返回一个指针,因为没有空引用这样的东西(黑客不计算在这里)

当然,这些只是现实的模型 - 实际上,没有发动机的汽车和没有汽车的发动机确实存在。如果适合,你甚至可以在汽车之间交换引擎。但是,将现实建模到此级别需要您付出更多努力,因此您需要决定模型的运行距离。

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

答案 1 :(得分:3)

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

只需要写

const engine& en = c.get_engine();

你的代码是奥克。

答案 2 :(得分:1)

从您引用的SO帖子中,给出的示例是:

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

这绝对不是好事。您将返回对从对象返回时将消失的对象的引用。

在你的情况下,

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

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

使用

engine& en = c.get_engine();

必然会导致编译错误。