C++ 返回对数据成员的引用

C++ 返回对数据成员的引用,c++,reference,C++,Reference,读过此文: 还有其他一些参考资料,我想知道这样的东西是否可以,或者我应该返回一个指针 #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 {

读过此文:

还有其他一些参考资料,我想知道这样的东西是否可以,或者我应该返回一个指针

#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;
}
#包括
类引擎
{
公众:
int cc;
};
班车
{
受保护的:
发动机工程;
公众:
car(无效):eng()
{
eng.cc=500;
}
常量引擎和获取引擎(无效)常量
{
返回引擎;
}
};
内部主(空)
{
汽车c=汽车();
引擎en=c。获取引擎();

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

只有你需要写作

const engine& en = c.get_engine();

您的代码没有问题。

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

int& getInt(void)
{
    int i;
    return i;
}
这绝对不好。您正在返回一个对象的引用,当您从函数返回时,该对象将消失

就你而言

const engine& get_engine(void) const
{
  return eng;
}
这是返回对象引用的一个非常有效的用法

使用

engine& en = c.get_engine();

必须导致编译器错误。

答案取决于您尝试建模的内容:

  • 如果发动机不能在其汽车的外部环境中存在,并且如果汽车不能在没有发动机的情况下存在,则返回一个引用是可以的-这意味着汽车将在您使用其发动机时存在
  • 如果引擎可以存在于其汽车的外部环境中,那么最好返回一个指针(最好是智能指针)。这样删除相应的汽车不会删除引擎
  • 如果一辆汽车没有引擎也可以存在,同样的情况也会发生:你需要返回一个指针,因为这里没有空引用(黑客不算在内)
当然,这些只是现实的模型——事实上,没有发动机的汽车和没有汽车的发动机都存在。如果合适的话,你甚至可以在汽车之间交换发动机。然而,将现实建模到这个水平需要你付出更多的努力,所以你需要决定你的模型能走多远


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

发动机&en=c.获取发动机();
将导致编译器错误。使用从getter返回的
常量&
是完全可以的。对于容器类访问操作,可能会考虑使用返回的非常量引用。如果您的工程师同事理解并能应用该概念和非拥有的引用,那么请删除您自己。返回引用ces一般来说并不是真正的邪恶。你应该注意,在你链接的问题中所做的邪恶的事情是:1.返回对一个对象的引用,该对象将超出范围并且不再存在。2.返回对一个动态分配对象的引用,并期望调用方知道他必须删除它。在第一个cas中是这样的e:
引擎en=c.获取引擎()
仅返回对象没有任何好处?例如,对整个对象有一个复制操作。@jayjay在第一个示例中,您创建了一个engine类型的新对象,它是car类原始子对象的副本。您可以更改此新对象。在第二种情况下,您可以不更改对象,因为它是一个常量引用法国。